返回目录
题意
给出n个人的姓名、年龄和拥有的财富,每次查询输出年龄在[agel,ageh],包括两端点的前m个人的信息。如果财富相同则按照年龄小的在前,如果年龄相同则按照姓名的字典序排
样例(可复制)
12 4
Zoe_Bill 35 2333
Bob_Volk 24 5888
Anny_Cin 95 999999
Williams 30 -22
Cindy 76 76000
Alice 18 88888
Joe_Mike 32 3222
Michael 5 300000
Rosemary 40 5888
Dobby 24 5888
Billy 24 5888
Nobody 5 0
4 15 45
4 30 35
4 5 95
1 45 50
样例输出
Case #1:
Alice 18 88888
Billy 24 5888
Bob_Volk 24 5888
Dobby 24 5888
Case #2:
Joe_Mike 32 3222
Zoe_Bill 35 2333
Williams 30 -22
Case #3:
Anny_Cin 95 999999
Michael 5 300000
Alice 18 88888
Cindy 76 76000
Case #4:
None
注意点
- 本题考察排序问题,难点在于中间两个测试点容易超时,如果每次查询都对某个年龄段进行排序,最多拿22分,第2个会超时,解决办法是使用预处理
- 预处理方法:由于题目说了m<100,则对某个年龄上的人进行财富排名后可以只取前100个人放在新的vaild即可
#include <bits/stdc++.h>
using namespace std;
struct person{
char name[10];
int age,money;
}per[100010],vaild[100010];
bool cmp(person a,person b){
if(a.money!=b.money)return a.money>b.money;
if(a.age!=b.age)return a.age<b.age;
return strcmp(a.name,b.name)<0;
}
int main(){
int n,k,Case=1;
int age[220]={0};
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++)scanf("%s %d %d",per[i].name,&per[i].age,&per[i].money);
sort(per,per+n,cmp);
int validnum=0;
for(int i=0;i<n;i++){
if(age[per[i].age]<100){
age[per[i].age]++;
vaild[validnum++]=per[i];
}
}
while(k--){
int m,agel,ageh,num=0;
scanf("%d %d %d",&m,&agel,&ageh);
printf("Case #%d:\n",Case++);
for(int i=0;i<n&&num<m;i++){
if(per[i].age<agel||per[i].age>ageh)continue;
printf("%s %d %d\n",per[i].name,per[i].age,per[i].money);
num++;
}
if(num==0)printf("None\n");
}
return 0;
}