题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4393
题目大意:有n个人参加比赛,他们在第一秒内跑了Fi米,在之后的时间他们的速度为Si米/秒,每一秒淘汰距离起点最远的人,求淘汰人的顺序。
题目思路:容易想到是优先队列,但是要考虑每次怎么更新新的距离。由于Si的范围很小,定义一个优先队列的数组,我可以把Si相同的人放入同一个优先队列内,按照Fi和Si排序。遍历所有的优先队列的首项,就能够找出跑的最远的人的id,然后把它给pop掉。一共有n个人,所以所有人淘汰会花费n秒。
AC代码:
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int MAXN = 105;
struct node{
int fi,id;
node(int fi,int id):fi(fi),id(id){}
bool operator <(const node a)const{
if(a.fi==fi) return a.id<id;
return a.fi>fi;
}
};
priority_queue<node> q[MAXN];
int main(){
int T;scanf("%d",&T);
int cae=0;
while(T--){
int n;scanf("%d",&n);
for(int i=1;i<=n;i++){
int x,y;
scanf("%d%d",&x,&y);
q[y].push(node(x,i));
}
printf("Case #%d:\n",++cae);
for(int i=0;i<n;i++){
int maxDis=-1,maxId,maxSi;
for(int j=1;j<=100;j++){
if(!q[j].empty()){
node p=q[j].top();
if(p.fi+j*i>maxDis || ( p.fi+j*i==maxDis && p.id<maxId)){
maxDis=p.fi+j*i;
maxId=p.id;
maxSi=j;
}
}
}
q[maxSi].pop();
if(i==0)
printf("%d",maxId);
else
printf(" %d",maxId);
}
printf("\n");
}
return 0;
}