3709: [PA2014]Bohater

3709: [PA2014]Bohater

或者:Bohater

题解

好狠啊这个题 z 要开 long long ,可能算掉血回血的时候会爆 long long 吧

首先把能回血的怪打死(不然你后面血不够咋办)

打回血怪的顺序按照消耗血量升序排列

然后再考虑杀掉血怪

当我们杀完所有怪物,最后的体力值是确定的

 然后我们倒着看,杀掉血怪的时候,我们当做将血瓶吐出来还给掉血怪,然后掉血怪把消耗的血再还给你,然后推回去,看看能不能到达杀回血怪最后的血量巅峰,所以倒着看,处理就和杀回血怪差不多了,倒着看是按照回血量升序,正着看就是降序了

把问题分成两部分:

1.处理回血怪,到达血量巅峰,按照耗血量升序排序

2.处理掉血怪,能不能从血量巅峰不降到0及以下(或者是看看能不能回到血量巅峰),按照回血量从大到小排序(正着看)

好狠啊这个题 z 要开 long long ,可能算掉血回血的时候会爆 long long 吧

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>

using namespace std;

inline int read()
{
    int ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'||ch>'9') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}

int n,up_num=0,down_num=0;
long long z;
struct node
{
    int d,a,num;
}up[100010],down[100010];

bool cmp1(node x,node y)
{
    return x.d <y.d ;
}

bool cmp2(node x,node y)
{
    return x.a >y.a ;
}

int main()
{
    n=read();z=read();
    int x,y;
    for(int i=1;i<=n;i++)
    {
        x=read();y=read();
        if(x<=y) up[++up_num].num =i,up[up_num].d =x,up[up_num].a =y;
        else down[++down_num].num =i,down[down_num].d =x,down[down_num].a =y;
    }
    sort(up+1,up+up_num+1,cmp1);
    sort(down+1,down+down_num+1,cmp2);
    for(int i=1;i<=up_num;i++)
    {
        if(up[i].d >=z){printf("NIE
");return 0;}
        else z=z-up[i].d +up[i].a ;
    }
    for(int i=1;i<=down_num;i++)
    {
        if(down[i].d >=z){printf("NIE
");return 0;}
        else z=z-down[i].d +down[i].a ;
    }
    printf("TAK
");
    for(int i=1;i<=up_num;i++)
      printf("%d ",up[i].num );
    for(int i=1;i<=down_num;i++)
      printf("%d ",down[i].num );
    return 0;
}
Z要开 long long
原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11238268.html