题目链接:点击打开链接
题目大意:略。
解题思路:剪枝:先按照题目要求排名后,因为撑死才输出100名,而把相同年龄有100之外的人排除掉可节省时间,这里主要用一个下标数组来跳过中间被过滤掉的下标。
AC 代码
#include<bits/stdc++.h> #include<cmath> #define mem(a,b) memset(a,b,sizeof a); #define INF 0x3f3f3f3f #define MOD 1000000007 using namespace std; typedef long long ll; const int maxn=1e5+10; int n,k; int ageCnt[250], idrr[maxn]; struct peo { string name; int age,val; }peos[maxn]; int cmp(peo p1,peo p2) { if(p1.val==p2.val) { if(p1.age==p2.age) return p1.name<p2.name; return p1.age<p2.age; } return p1.val>p2.val; } int main() { char name[15]; int kase=1; while(~scanf("%d%d",&n,&k)) { for(int i=0;i<n;i++) { scanf("%s%d%d",name,&peos[i].age,&peos[i].val); peos[i].name=name; } sort(peos,peos+n,cmp); // 解题核心地方 int idCnt=0; for(int i=0,a;i<n;i++) { a=peos[i].age; if(ageCnt[a]<100) { ageCnt[a]++; idrr[idCnt++]=i; } } int t,l,r,cnt; while(k--) { scanf("%d%d%d",&t,&l,&r); printf("Case #%d:\n",kase++); cnt=0; for(int i=0,j;i<idCnt;i++) { j=idrr[i]; if(l<=peos[j].age && peos[j].age<=r && cnt<t) { printf("%s %d %d\n",peos[j].name.c_str(),peos[j].age,peos[j].val); cnt++; } } if(!cnt) puts("None"); } } return 0; }