题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=115361#problem/D
题意大致是:给出最多50000个人,拥有最初速度F和1秒后的速度V,(F<=500,V<=100)每秒将速度最快的那个人淘汰,按淘汰的人的顺序输出他们的序号。
思路:由于人数很多,用暴力更新每秒淘汰的人显然会TLE。注意到F很小,那么对于任意两个人来说,即使有500的路程差,速度快的那个人哪怕是每秒只快1米,在501秒后就能超越,也就是说,501秒以后速度越快的人就一直处于快的地位,速度一样的人,F大的先被淘汰,再一样,按照序号小的先淘汰即可;那么在501秒以后只要按照这个方法排一个序即可。而对于501秒以内的,只要暴力模拟每秒淘汰最快的即可。
当然,这是按照F范围小赖考虑的,V范围小的方法还不会- -,,下次会了再补上。
下面给出AC代码:
#include <stdio.h>
#include <algorithm>
#include <set>
#include <string.h>
using namespace std;
struct node
{
int id;
int v;
int f;
int s;
}P[+];
int tot;
bool cmp(node A,node B)
{
if(A.v==B.v)
{
if(A.f==B.f)
{
return A.id<B.id;
}
else return A.f>B.f;
}
else return A.v>B.v;
} int main()
{
int T;
scanf("%d",&T);
for(int kace=;kace<=T;kace++)
{
tot=;
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int f,v;
scanf("%d%d",&f,&v);
P[++tot]=(node){i,v,f,f};
}
printf("Case #%d:\n",kace);
for(int i=;i<=;i++)
{
if(i>n) break;
int id=;
int maxsum=-;
for(int j=;j<=tot;j++)
{
if(i!=&&P[j].s!=-) P[j].s+=P[j].v;
if(maxsum<P[j].s) {id=P[j].id;maxsum=P[j].s;}
}
if(i!=) printf(" ");
printf("%d",id);
P[id].s=P[id].f=P[id].v=-;
}
sort(P+,P++tot,cmp);
for(int i=;i<=n-;i++)
{
printf(" %d",P[i].id);
}
puts("");
}
return ;
}