您的位置:首页 > 其它

PAT-A 1055. The World's Richest (25)

2017-03-01 20:13 337 查看
题目链接在此

题意

给定N个人的信息(姓名、年龄、财富值),然后进行K次查询,每次查询要求输出年龄在[amin,amax]之间的财富值从小到大的前M个人的信息。如果财富值相同,则按照年龄从小到大排序,年龄相同则按照名字的字典序排序。

思路及代码

思路1

首先根据年龄排序,然后根据输入的amin和amax,找到这个区间内的人,然后对这个区间内的人再按照输出的要求排序。

这种思路会有两个测试点超时。

然后为了减少使用sort函数,使用一个temp结构体数组,用来保存按照年龄排序的结果,这样就可以少用sort数组去根据年龄排序,只需要在temp和richer数组赋值操作即可,这样做仍然有一个测试点超时。

思路1代码

两个测试点超时的代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

struct INFO{
char name[9];
int age;
int wealth;
}richer[100001];

//sort by age
bool cmp_age(INFO a, INFO b){
return a.age < b.age;
}

//sort for final rules
bool cmp(INFO a, INFO b){
if(a.wealth != b.wealth) return a.wealth > b.wealth;
else if(a.age != b.age) return a.age < b.age;
else return (strcmp(a.name, b.name ) <0 );
}

bool cmp_test(INFO a, INFO b){
return a.wealth < b.wealth;
}

int main(){

int N,K,M;
scanf("%d %d",&N, &K);
getchar(); //吸收换行

for(int
4000
i = 0; i < N; i++){
scanf("%s %d %d",&richer[i].name, &richer[i].age, &richer[i].wealth);
}

//get K queries & get result
int C, amin, amax; //保存K个查询的信息
for(int i = 0 ; i < K; i++){

sort(richer, richer+N, cmp_age);

scanf("%d",&C);
scanf("%d",&amin);
scanf("%d",&amax);

//find richers whose age in [amin,amax]
int start;
for(start = 0; start < N; start++){
if(richer[start].age >= amin){
break;
}
}

int end;
for(end = start; end < N; end++){
if(richer[end].age > amax){
break;
}
}

sort(richer+start, richer+end, cmp);

printf("Case #%d:\n",i+1);
if(start == end){
printf("None\n");
}else{

if(C > (end-start)){ //比如数据中只有3个,而需要打印前4 的情况
C = end-start;
}

//print the results
for(int j = start; j < start+C; j++){
printf("%s %d %d\n",richer[j].name, richer[j].age, richer[j].wealth);
}
}

}

return 0;
}


一个测试点超时的代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

struct INFO{
char name[9];
int age;
int wealth;
//  bool flag;
}richer[100001],temp[100001];

//sort by age
bool cmp_age(INFO a, INFO b){
return a.age < b.age;
}

//sort for final rules
bool cmp(INFO a, INFO b){
if(a.wealth != b.wealth) return a.wealth > b.wealth;
else if(a.age != b.age) return a.age < b.age;
else return (strcmp(a.name, b.name ) <0 );
}

bool cmp_test(INFO a, INFO b){
return a.wealth < b.wealth;
}

// temp to richer
void tempToRicher(int N){
for(int i = 0; i < N; i++){
richer[i] = temp[i];
}
}

int main(){

int N,K,M;
scanf("%d %d",&N, &K);
getchar(); //吸收换行

for(int i = 0; i < N; i++){
scanf("%s %d %d",&richer[i].name, &richer[i].age, &richer[i].wealth);
}

//sort by age
sort(richer, richer+N, cmp_age);
//put ordered richer to temp
for(int i = 0; i < N; i++){
temp[i] = richer[i];
}

//get K queries & get result
int C, amin, amax; //保存K个查询的信息
for(int i = 0 ; i < K; i++){

//      sort(richer, richer+N, cmp_age);

scanf("%d",&C);
scanf("%d",&amin);
scanf("%d",&amax);

//find richers whose age in [amin,amax]
int start;
for(start = 0; start < N; start++){
if(richer[start].age >= amin){
break;
}
}

int end;
for(end = start; end < N; end++){
if(richer[end].age > amax){
break;
}
}

sort(richer+start, richer+end, cmp);

printf("Case #%d:\n",i+1);
if(start == end){
printf("None\n");
}else{

if(C > (end-start)){ //比如数据中只有3个,而需要打印前4 的情况
C = end-start;
}

//print the results
for(int j = start; j < start+C; j++){
printf("%s %d %d\n",richer[j].name, richer[j].age, richer[j].wealth);
}
}

tempToRicher(N);
}

return 0;
}


思路2

既然是因为查找元素过多而超时的,那么就应该减少查找元素堆的规模。这里由于M<=100,所以将每个年龄中财富在前100名的人的信息存放在一个数组中,输出的时候到这个数组中去取即可。

思路2代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

struct INFO{
char name[9];
int age;
int wealth;
//  bool flag;
}richer[100001],valid[100001]; //valid 保存每个年龄前100人的信息

//sort for final rules
bool cmp(INFO a, INFO b){
if(a.wealth != b.wealth) return a.wealth > b.wealth;
else if(a.age != b.age) return a.age < b.age;
else return (strcmp(a.name, b.name ) <0 );
}

bool cmp_test(INFO a, INFO b){
return a.wealth < b.wealth;
}

int main(){

int N,K,M;
scanf("%d %d",&N, &K);
getchar(); //吸收换行

for(int i = 0; i < N; i++){
scanf("%s %d %d",&richer[i].name, &richer[i].age, &richer[i].wealth);
}

//sort by age
sort(richer, richer+N, cmp);

//将每个年龄排名前100的人的信息放到一个数组中,提高查找效率
int num[210] = {0}; //保存每个年龄的人数

int many = 0; //保存valid数组的大小
for(int i = 0; i < N; i++){
if(num[richer[i].age] < 100) { //年龄为richer[i].age的人数小于100人时
valid[many++] = richer[i]; //将richer[i]加入数组中
num[richer[i].age]++; // 年龄为richer[i].age的人数+1
}
}

//get K queries & get result
int C, amin, amax; //保存K个查询的信息
for(int i = 0 ; i < K; i++){

scanf("%d",&C);
scanf("%d",&amin);
scanf("%d",&amax);

printf("Case #%d:\n",i+1);
int count = 0; //已经输出的人数
for(int j = 0; j < many && count<C; j++){
if(valid[j].age>=amin && valid[j].age<=amax){
printf("%s %d %d\n",valid[j].name, valid[j].age, valid[j].wealth);
count++;
}
}

if(count == 0){
printf("None\n");
}

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: