题目大意:
给出N个人的姓名、年龄及其拥有的财富值,然后进行K次查询。每次查询要求输出年龄范围在[AgeL, AgeR]的财富值从大到小的前M人的信息。
如果财富值相同,则年龄小的优先;如果年龄也相同,则姓名的字典序小的优先。
算法思路:
总体思路就是先排序在按照要求输出结果,这里的排序可以使用排序函数,也可以使用set的自定义排序,这里选择了第二种,无论哪一种排序方法,
最终都会导致测试超时,最关键的点在于M的取值范围,M最大为100,说明每一个年龄的人数最大为100,那么只需要将每一个年龄的前100名添加进新的容器中,然后再进行遍历输出就不会导致超时。
提交结果:
第一次测试:使用sort函数,导致测试点2运行超时。
第二次测试:使用set自定义排序函数,导致测试点1超时。
第三次测试:将排完序后的元素的每个年龄的前100名取出来然后遍历,测试通过。
注意点:
1、如果不将每一个年龄的前100个人取出来然后再查询的话,对于使用sort函数方式会导致测试点2超时,使用set方式会导致测试点1超时。
2、存放每个年龄的数组大小得设置为1000以上,不然会导致测试错误
3、暴力求解可得22分。
AC代码:
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
#include<string>
using namespace std;
struct People{
string name;
int age;
int worth;
};
struct cmp{
bool operator()(const People &a,const People &b){
if (a.worth!=b.worth){
return a.worth>b.worth;
} else if (a.age!=b.age){
return a.age<b.age;
} else {
return a.name<b.name;
}
}
};
int main(){
int N,K;// 总人数和查询次数
scanf("%d %d",&N,&K);
set<People,cmp> peoples;
char name[20];
People people;
for (int i = 0; i < N; ++i) {
scanf("%s %d %d",name,&people.age,&people.worth);
people.name = name;
peoples.insert(people);
}
// 将每个年龄的人中前100名保存到数组sorted_people中
vector<People> sorted_people;
int age_num[100001]; // 存放年龄为i的人数,这里的下标不能是200,得是总人数加一,不过1000就可以通过所有测试点了
for(auto &peo : peoples){
if (age_num[peo.age]<100){
++age_num[peo.age];
sorted_people.push_back(peo);
}
}
int M,Amin,Amax;
for (int j = 0; j < K; ++j) {
scanf("%d %d %d",&M,&Amin,&Amax);
// 输出结果
printf("Case #%d:\n",j+1);
int index = 0;
bool printed = false;// 是否有输出
for (auto & peo : sorted_people) {
if (peo.age>=Amin&&peo.age<=Amax){
if (index==M) break;
printf("%s %d %d\n",peo.name.c_str(),peo.age,peo.worth);
++index;
printed = true;
}
}
if (!printed){
printf("None\n");
}
}
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。