题目链接: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;
}

 

收藏 打印