3709: [PA2014]Bohater

Description

在一款电脑游戏中,你需要打败n只怪物(从1到n编号)。为了打败第i只怪物,你需要消耗d[i]点生命值,但怪物死后会掉落血药,使你恢复a[i]点生命值。任何时候你的生命值都不能降到0(或0以下)。请问是否存在一种打怪顺序,使得你可以打完这n只怪物而不死掉

Input

第一行两个整数n,z(1<=n,z<=100000),分别表示怪物的数量和你的初始生命值。
接下来n行,每行两个整数d[i],a[i](0<=d[i],a[i]<=100000)

Output

第一行为TAK(是)或NIE(否),表示是否存在这样的顺序。
如果第一行为TAK,则第二行为空格隔开的1~n的排列,表示合法的顺序。如果答案有很多,你可以输出其中任意一个。

Sample Input

3 5
3 1
4 8
8 3

Sample Output

TAK
2 3 1

贪心
首先。打了能加血的肯定要先干掉。因为是加血所以我们尽量满足消耗的限定就行,所以我们把这部分加血的d[i]从小到大排序然后顺次消灭
对于打了减血的,我们反过来考虑。消耗和回复反过来看,那就和上面一种情况一样了。把回复降序排序就好。
如果消耗等于回复。那随便放在上面两种情况的任意一种都可以。
最后。。记得开longlong。因为10^5*10^5=10^10>2147483647

#include<cstdio>
#include<algorithm>
using namespace std;
struct npc
{
     long long d,g;
     int x;
     long long xx;
}a[100001];
inline bool cmp1(npc x,npc y)
{
     if(x.xx<y.xx)
          return true;
     return false;
}
inline bool cmp2(npc x,npc y)
{
     if(x.d<y.d)
          return true;
     return false;
}
inline bool cmp3(npc x,npc y)
{
     if(x.g>y.g)
          return true;
     return false;
}
int main()
{
     int n;
     long long z;
     scanf("%d%lld",&n,&z);
     int i;
     for(i=1;i<=n;i++)
     {
          scanf("%lld%lld",&a[i].d,&a[i].g);
          a[i].x=i;
          a[i].xx=a[i].d-a[i].g;
     }
     sort(a+1,a+1+n,cmp1);
     int td=0;
     for(i=1;i<=n;i++)
          if(a[i].g-a[i].d<=0)
               break;
     i--;
     sort(a+1,a+1+i,cmp2);
     td=i;
     for(i=td;i<=n;i++)
          if(a[i].g-a[i].d<0)
               break;
     if(i<=n)
          sort(a+i,a+1+n,cmp3);
     int s=0;
     for(i=1;i<=n;i++)
     {
     	  if(z<=a[i].d)
          {
          	   printf("NIE\n");
               return 0;
          }
          z=z+a[i].g-a[i].d;
     }
     printf("TAK\n");
     printf("%d",a[1].x);
     for(i=2;i<=n;i++)
          printf(" %d",a[i].x);
     printf("\n");
     return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值