这道题目大概意思就是给出N个人的名字,年龄,净财产,给出K个查询,每次输入查询财产排名最高的M个人,年龄范围在Amin~Amax,如果没有人符合输出None,可能会存在人数不到M的情况,这样只输出满足的即可。如果每次把年龄区间的人找出来再排序会超时,我的想法是先排序,用两个数组v1[i][j]代表年龄大于等于i的第j个人,v2[i][j]代表年龄小于等于i的第j个人,再用minage和maxage代表年龄的范围,最后每次查询需要计算v1[Amin]和v2[Amax]的交集,这道题时间给的太少,刚好卡着过,有时间会去学习更好的算法。
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cstring>
using namespace std;
int N,K;
struct node
{
char name[10];
int age,val;
bool operator < (const node& rhs) const
{
return age<rhs.age;
}
}p[100005];
int v1[205][100005],v2[205][100005];
int n[1005],l[1005],r[1005];
bool cmp(node a,node b)
{
if(a.val!=b.val) return a.val>b.val;
if(a.age!=b.age) return a.age<b.age;
return strcmp(a.name,b.name)<0;
}
int main()
{
cin>>N>>K;
int maxage=0,minage=200;
int maxpage=0,minpage=200;
for(int i=0;i<N;i++)
{
scanf("%s %d %d",p[i].name,&p[i].age,&p[i].val);
maxpage=max(maxpage,p[i].age);
minpage=min(minpage,p[i].age);
}
sort(p,p+N,cmp);
for(int i=0;i<K;i++)
{
scanf("%d %d %d",&n[i],&l[i],&r[i]);
maxage=max(r[i],maxage);
minage=min(minage,l[i]);
}
maxage=min(maxage,maxpage);
minage=max(minage,minpage);
for(int i=0;i<N;i++)
{
for(int j=minage;j<=p[i].age;j++)
{
++v1[j][0];
v1[j][v1[j][0]]=i;
}
for(int j=p[i].age;j<=maxage;j++)
{
++v2[j][0];
v2[j][v2[j][0]]=i;
}
}
for(int i=0;i<K;i++)
{
l[i]=max(l[i],minage);r[i]=min(maxage,r[i]);
int sz2=v2[r[i]][0]+1,sz1=v1[l[i]][0]+1;
int s1=1,s2=1,cnt=0;
printf("Case #%d:",i+1);
while(s1<sz1&&s2<sz2&&cnt<n[i])
{
if(v1[l[i]][s1]<v2[r[i]][s2])
{
s1++;
}
else if(v1[l[i]][s1]>v2[r[i]][s2])
{
s2++;
}
else
{
printf("
%s %d %d",p[v1[l[i]][s1]].name,p[v1[l[i]][s1]].age,p[v1[l[i]][s1]].val);
s1++;
s2++;
cnt++;
}
}
if(cnt==0) printf("
None");
if(i!=K-1) puts("");
}
return 0;
}