题目链接:点击打开链接
题目大意:略。
解题思路:剪枝:先按照题目要求排名后,因为撑死才输出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;
}