Each player has a single straight runway. And ZL will throw a nail every second end to the farthest player's runway. After the "BOOM", this player will be eliminated. If more then one players are NO.1, he always choose the player who has the smallest ID.
Input
In the first line there is an integer T (T <= 20), indicates the number of test cases.
In each case, the first line contains one integer n (1 <= n <= 50000), which is the number of the players.
Then n lines follow, each contains two integers Fi(0 <= Fi <= 500), Si (0 < Si <= 100) of the ith player. Fi is the way can be run in first second and Si is the speed after one second .i is the player's ID start from 1.
Hint
Huge input, scanf is recommended.
Huge output, printf is recommended.
Output
For each case, the output in the first line is "Case #c:".
c is the case number start from 1.
The second line output n number, separated by a space. The ith number is the player's ID who will be eliminated in ith second end.
Sample Input
2
3
100 1
100 2
3 100
5
1 1
2 2
3 3
4 1
3 4
Sample Output
Case #1:
1 3 2
Case #2:
4 5 3 2 1
题意:一年一度的学校自行车比赛开始了。ZL决定干扰比赛。他通过以前的比赛录像获得了运动员的信息。运动员在第一秒钟可以跑F米,然后每秒钟可以跑S米。每个球员都有一条直线跑道。ZL每隔一秒就会把一颗钉子钉到最远的球员的跑道上。“轰”的一声之后,这个玩家就被淘汰了。如果两个球员一样远,他总是选择ID最小的球员。
思路:首先我们可以想到需要排序,当距离一样远时按ID号排序,其它按距离排序,这是我们可以想到把所有数据压入优先队列排序,但除了第一秒可以直接按F和ID排序,其他时候需要加上S,在不同秒时优先队列里的元素是不一样的,所以我们需要处理这些部分,因此我们只能在优先队列里存入第一秒的数据,其余数据可以通过for循环不断更新。
for(int i=0;i<n;i++)
{
ll maxx=-9999,now;
for(int j=1;j<=100;j++)//s的范围最大到100
{
if(!q[j].empty())
{
a=q[j].top();
if(a.fi+j*i>maxx)
{
maxx=a.fi+j*i;
now=j;
}
else if(a.fi+j*i==maxx&&a.num<(q[now].top()).num)
{
now=j;
}
}
}
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
struct node
{
ll fi;
ll si;
ll num;
friend bool operator<(node a,node b)
{
if(a.fi!=b.fi)
return a.fi<b.fi;
else
return a.num>b.num;
}
};
int main()
{
ll t,cas=1;
scanf("%lld",&t);
while(t--)
{
ll n,ant=1;
scanf("%lld",&n);
priority_queue<node>q[110];
node a;
for(int i=0;i<n;i++)
{
scanf("%lld%lld",&a.fi,&a.si);
a.num=ant++;
q[a.si].push(a);
}
printf("Case #%lld:\n",cas);
cas++;
for(int i=0;i<n;i++)
{
ll maxx=-9999,now;
for(int j=1;j<=100;j++)
{
if(!q[j].empty())
{
a=q[j].top();
if(a.fi+j*i>maxx)
{
maxx=a.fi+j*i;
now=j;
}
else if(a.fi+j*i==maxx&&a.num<(q[now].top()).num)
{
now=j;
}
}
}
if(i!=n-1)
{
printf("%lld ",q[now].top().num);
}
else
{
printf("%lld\n",q[now].top().num);
}
q[now].pop();
}
}
return 0;
}