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; }