题意:n个人比赛(标号1~n),每个人有两个速度 f 和 s,分别代表第1s的速度和之后的速度。每秒结束时第一名淘汰,输出所有人的淘汰顺序。如果并列第一,那么淘汰标号小的。0<=f<=500,0<s<=100
思路:可以看到0<s<=100,相同s的放到一个优先队列里,优先队列先按 f 从大到小排,f 相同按标号从小到大排。
每次让s从1到100枚举,取出距离最大的即可。
#include<iostream> #include<stdio.h> #include<queue> using namespace std; struct node{ int index; int f; bool operator < (const node &a) const { if(f!=a.f)return f<a.f;//最大值优先 return index>a.index;//最小值优先 } }; int main(){ priority_queue<node>mypq[105]; node a,tmp; int t,n,s,i,j,k; int fast,sid; scanf("%d",&t); for(i=1;i<=t;++i){ scanf("%d",&n); for(j=1;j<=n;++j){ scanf("%d%d",&a.f,&s); a.index=j; mypq[s].push(a); } printf("Case #%d: ",i); for(j=0;j<n;++j){//秒,1s出队1个 fast=-1;sid=1; for(k=1;k<=100;++k){//速度s if(!mypq[k].empty()){ tmp=mypq[k].top(); if(tmp.f+k*j>fast){ fast=tmp.f+k*j; sid=k; } else if(tmp.f+k*j==fast&&tmp.index<mypq[sid].top().index) sid=k; } } printf("%d",mypq[sid].top().index); mypq[sid].pop(); if(j<n-1)printf(" "); } printf(" "); } return 0; }