PAT A1055 The World’s Richest
Sample Input:
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
Sample Output:
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
- 题意:
查找给出年龄段,前M富有的人
排序规则:
-
思路 1:
暴力解法,排序后,每次查询都从头到尾遍历,输出符合条件的m个元素 -
code 1:
#include <iostream>
#include <stdio.h>
#include <string>
#include <algorithm>
using namespace std;
const int maxn = 110000;
int n, m, k;
struct Person{
string name;
int age, worth;
}per[maxn];
bool cmp(Person a, Person 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(){
scanf("%d %d", &n, &k);
for(int i = 0; i < n; ++i){
cin >> per[i].name >> per[i].age >> per[i].worth;
}
sort(per, per+n, cmp);
//Query:
int low, up, cnt, idex = 1;
for(int i = 0; i < k; ++i){
scanf("%d %d %d", &m, &low, &up);
printf("Case #%d:\n", idex);
cnt = 0;
for(int j = 0; j < n; ++j){
if(low <= per[j].age && per[j].age <= up && cnt < m){
printf("%s %d %d\n", per[j].name.c_str(), per[j].age, per[j].worth); //!!!:Wrong 1:超时警告
cnt++;
}
}
if(cnt == 0) printf("None\n");
idex++;
}
return 0;
}
-
Wrong 1: 若用cout 输出样例2、3会超时
-
思路 2:
提前预处理:
因为查询M<=100,也就是说,最大查到排位100,所以可以先把各年龄段 排名超过100的排除 ,即 每个年龄排名超过100的选手直接pass掉 -
code 2:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110000;
int n, m, k;
int Age[210] = {0};
struct Person{
string name;
int age, worth;
}per[maxn], valid[maxn];
vector<Person> v[210];
bool cmp(Person a, Person 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(){
scanf("%d %d", &n, &k);
for(int i = 0; i < n; ++i){
cin >> per[i].name >> per[i].age >> per[i].worth;
}
sort(per, per+n, cmp);
//预处理:
int v_idex = 0;
for(int i = 0; i < n; ++i){
if(Age[per[i].age] <= 100){
Age[per[i].age]++;
valid[v_idex++] = per[i];
}
}
//Query:
int low, up, cnt, idex = 1;
for(int i = 0; i < k; ++i){
scanf("%d %d %d", &m, &low, &up);
printf("Case #%d:\n", idex);
cnt = 0;
for(int j = 0; j < v_idex && cnt < m; ++j){
//!!!:Wrong 1
if(low <= valid[j].age && valid[j].age <= up){
printf("%s %d %d\n", valid[j].name.c_str(), valid[j].age, valid[j].worth);
cnt++;
}
}
if(cnt == 0) printf("None\n");
idex++;
}
return 0;
}
-
Wrong 1:注意for的终止条件,必须多加一条cnt < m, 不然会多遍历无用数据,导致超时
-
T2 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
struct Peo{
char name[10];
int age, net_worth;
}peo[maxn];
bool cmp(Peo a, Peo b){
if(a.net_worth != b.net_worth) return a.net_worth > b.net_worth;
else if(a.age != b.age) return a.age < b.age;
else return strcmp(a.name, b.name) < 0;
}
int main(){
int n, k;
scanf("%d %d", &n, &k);
for(int i = 0; i < n; ++i){
scanf("%s %d %d", peo[i].name, &peo[i].age, &peo[i].net_worth);
}
sort(peo, peo+n, cmp);
for(int i = 1; i <= k; ++i){
int m, a_min, a_max, cnt = 0;
scanf("%d %d %d", &m, &a_min, &a_max);
printf("Case #%d:\n", i);
for(int j = 0; j < n && m > 0; ++j){
int a = peo[j].age;
if(a_min <= a && a <= a_max){ //Wrong 1:闭区间!
m--; cnt++;
printf("%s %d %d\n", peo[j].name, peo[j].age, peo[j].net_worth);
}
}
if(cnt == 0) printf("None\n");
}
return 0;
}