1. 程式人生 > >hdu 4393Throw nails(優先佇列)

hdu 4393Throw nails(優先佇列)

題目連結: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;
}