题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805421066272768
注意:
若不进行预处理,在第2个测试点出现“运行超时”的错误
注意到 M 的范围仅在100之内,因此可以预处理:将每个年龄中财富在前100名以内的人全部存到另一个数组中(因为某个年龄中财富值在100名以外的人永远不会被输出),后面查询的操作均在这个新数组中进行。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 100010;
struct People{
char id[10];
int age;
int money;
}peo[maxn], valid[maxn];
int Age[maxn] = {0};
bool cmp(People a, People b){
if(a.money != b.money)
return a.money > b.money;
else if(a.age != b.age)
return a.age < b.age;
else
return strcmp(a.id, b.id) < 0;
}
int main(){
int n, k;
scanf("%d%d", &n, &k);
for(int i = 0; i < n; i++){
scanf("%s %d %d", peo[i].id, &peo[i].age, &peo[i].money);
}
sort(peo, peo+n, cmp);
// 财富值在100名以内的人加入新数组,预处理,避免超时
int validNum = 0;
for(int i = 0; i < n; i++){
if(Age[peo[i].age] < 100){
Age[peo[i].age]++;
valid[validNum++] = peo[i];
}
}
for(int i = 0; i < k; i++){
int num, amin, amax;
scanf("%d%d%d", &num, &amin, &amax);
printf("Case #%d:\n", i+1);
int count = 0;
for(int j = 0; j < validNum && count < num; j++){
if(valid[j].age >= amin && valid[j].age <= amax){
printf("%s %d %d\n", valid[j].id, valid[j].age, valid[j].money);
count++;
}
}
if(count == 0)
printf("None\n");
}
return 0;
}
2021.2.21
/**
* 02.21 18:17
* 1055 The World's Richest (25 分)
*
**/
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
struct Person {
char name[10];
int age;
int worth;
} p[100010];
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 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", p[i].name, &p[i].age, &p[i].worth);
}
sort(p, p + n, cmp);
//开始查询
for (int i = 0; i < k; i++) {
int m, min, max;
scanf("%d%d%d", &m, &min, &max);
printf("Case #%d:\n", i + 1);// 标题Case
int ok[100] = {0};
// 遍历整个结构体数组,看有没有符合条件的,如果有符合条件的,将下标存入ok数组中
int cnt = 0;
for (int j = 0; j < n; j++) {
if (p[j].age >= min && p[j].age <= max) {
ok[cnt++] = j;
// 这里如果不加这个,测试点1超时,
// 因为这里我们找到m个符合条件的值就不用继续遍历整个结构体了,否则每次查询都要循环n个结构体,开销很大
if(cnt == m)
break;
}
}
// 如果数组ok中无值,就输出none,否则遍历m个存入的下标对应的结构体
if(cnt == 0){
printf("None\n");
}else{
// 取 在年龄段的符合条件的人数 和 题目给定要m个人的最小值
// 因可能出现 符合条件人多,但只用输出m个,例Case1
// 也可能出现 符合条件人少,但要输出m个,符合条件的不过m个,例Case2
int min = (cnt < m) ? cnt : m;
for (int l = 0; l < min; l++){
printf("%s %d %d\n", p[ok[l]].name, p[ok[l]].age, p[ok[l]].worth);
}
}
}
return 0;
}