[PAT解题报告] The World's Richest
简单题,就是排序……
每个人有三个属性: 年龄,财富,姓名。
题目要求: 输出一个年龄段范围内财富最多的m个人。
主要是查询有多组,所以我们不能反复排序。但是m <=
100,所以我们把每个年龄财富财富最多的(至多)100个人保存下来就可以了。最多10^5人,查询最多10^3个,所以除去排序,复杂度不过是10
^ 8 ,可以接受。
排序要排两次:
先按照 年龄、 财富、 姓名的顺序排序,这样年龄相同的人在一起,并且财富是由大到小的,我们对每个年龄的人取财富前100,存起来,因为无论怎么查询,后面的人都不会被输出——最多100人嘛。而且根据题意年龄不超过200,所以这一步下来我们剩余的人最多也就是20000人了——比10^5略小。
先按照 年龄、 财富、 姓名的顺序排序,这样年龄相同的人在一起,并且财富是由大到小的,我们对每个年龄的人取财富前100,存起来,因为无论怎么查询,后面的人都不会被输出——最多100人嘛。而且根据题意年龄不超过200,所以这一步下来我们剩余的人最多也就是20000人了——比10^5略小。
第二次就是按照财富,年龄,姓名的顺序就可以了,查询结果肯定在我们排好顺序的数组里。对每个查询,我们从头遍历一次数组,看一下那个人的年龄是否在我们要的年龄段里——因为按财富排序之后年龄就乱了,并且注意最多输出m个就可以了。
注意: 没有结果的时候,输出None
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
struct node {
char name[55];
int age,worth;
};
bool cmp1(const node &a,const node &b) {
if (a.age < b.age) {
return true;
}
if (a.age > b.age) {
return false;
}
if (a.worth > b.worth) {
return true;
}
if (a.worth < b.worth) {
return false;
}
return strcmp(a.name,b.name) < 0;
}
bool cmp2(const node &a,const node &b) {
if (a.worth > b.worth) {
return true;
}
if (a.worth < b.worth) {
return false;
}
if (a.age < b.age) {
return true;
}
if (a.age > b.age) {
return false;
}
return strcmp(a.name , b.name) < 0;
}
node p[100005];
int main() {
int n,m;
scanf("%d%d",&n,&m);
for (int i = 0; i < n; ++i) {
int a,w;
scanf("%s%d%d",p[i].name,&p[i].age,&p[i].worth);
}
sort(p , p + n, cmp1);
int have = 0;
for (int i = 0; i < n;) {
for (int j = i; (i < n) && (p[j].age == p[i].age); ++i) {
if (i - j < 100) {
p[have++] = p[i];
}
}
}
sort(p, p + have, cmp2);
for (int i = 1; i <= m; ++i) {
int num,from,to;
scanf("%d%d%d",&num,&from,&to);
printf("Case #%d:\n",i);
int n = 0;
for (int j = 0;(n < num) && (j < have); ++j) {
if ((p[j].age >= from) && (p[j].age <= to)) {
++n;
printf("%s %d %d\n",p[j].name,p[j].age,p[j].worth);
}
}
if (n == 0) {
puts("None");
}
}
return 0;
}
原题链接: http://www.patest.cn/contests/pat-a-practise/1055