Throw nails HDU 4393

The annual school bicycle contest started. ZL is a student in this school. He is so boring because he can't ride a bike!! So he decided to interfere with the contest. He has got the players' information by previous contest video. A player can run F meters the first second, and then can run S meters every second. 
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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值