“疲劳”传说
(legend.pas/c/cpp)
【题目描述】
炉石传说:魔兽英雄传是一款由暴雪开发的非常流行的游戏。这个问题建立在这个游戏的基础上,但是即使你不知道这个游戏,你也能非常轻松的解决这个问题。
每一局游戏是两个对手1v1的比赛。炉石传说的游戏方式是回合制,每个玩家轮流打出自己手中的牌。
每个玩家可以选择一个“英雄”,一个魔兽争霸中的重要人物。每个英雄有它独特的英雄技能。每个英雄有30滴血,并且如果他的血量减少到0 以下(包括0),英雄就会死亡、控制他的玩家就输掉了游戏。
在回合开始,玩家需要从他们的牌库中抽一张卡——牌库由玩家在游戏前挑选好的30张牌组成。在回合中,玩家可以选择使用卡牌或是使用英雄技能。然而,他们的行动将会消耗法力水晶,这个限制促使玩家策略性地规划他们的行动。每个玩家由1个法力水晶开局,在他们每个回合的开始都会多获得一个新的空法力水晶直到达到10个法力水晶的上限,并且将恢复所有法力水晶。
然而,一旦一个玩家抽光了他的牌库,从空牌库中抽卡会导致他们受到“疲劳”的伤害。“疲劳”在刚开始对玩家造成1点伤害,但是每次伤害都会加1。
注意,即使牌库为空也必须抽卡,即牌库为空后每回合都需要受到“疲劳”的伤害
现在,考虑这样一种情况:玩家手中的卡已经用完,两个玩家都有10个法力水晶上限,并且每个玩家在回合开始时都会获得10个法力水晶。
那意味着,每回合,每个玩家需要按顺序执行两个操作:
(1) 从空牌库中抽卡
(2) 使用他们的英雄技能(英雄技能消耗两个法力水晶并且每回合只能使用一次)
定义n为英雄的血量,n不超过30。注意:英雄的血量不能超过其上限30。
定义m为英雄的护甲,只有当英雄的护甲降为0时才会减少英雄的血量。英雄护甲没有上限。
注意,这里的护甲属于"消耗品",即如果受到伤害使护甲减少,护甲在这之后都不会恢复。
为了简化问题,我们给出四个英雄可供选择:
1 吉安娜 火焰冲击 对任意目标造成一点伤害
2 雷克萨 稳固射击 对敌方英雄造成两点伤害
3 加尔鲁什 全副武装 获得两点护甲
4 安度因 次级治疗术 回复两滴血
给你两个玩家的英雄编号,英雄血量,英雄护甲,两个英雄都按照最优策略行动,请问第一个玩家能获胜吗?(假设两人还未受到“疲劳”伤害)
【输入格式】
第一行包括整数T表示包含T组数据。
对于每组数据:第一行包括三个整数X1,N1,M1,代表第一个玩家的英雄编号,英雄血量与英雄护甲。
第二行包括三个整数X2,N2,M2代表第二个玩家的英雄编号,英雄血量与英雄护甲。
【输出格式】
对于每组数据,如果第一个玩家能获胜,输出“YES”,否则输出“NO”
Sample Input |
Sample Output |
2 1 10 3 2 5 10 3 10 10 4 10 10 |
NO NO |
【数据范围与约定】
对于50%的数据,X1,X2<=2
对于100%的数据,T<=100,保证输入数据合法且运算过程中所有数不超过32位整数
题解:一个大模拟,注意血量和护甲的区别,人死了不能再发动技能;
#include <bits/stdc++.h> using namespace std; int x1,x2,hp1,hp2,de1,de2; int tot1,tot2; int att[5]={0,1,2,-2,-2}; int attack(int cnt) { tot1-=cnt; if(tot1<=0){ return 0; } if(x1<=2) tot2-=att[x1]; else if(x1==3) tot1-=att[x1]; else{ if(hp1>tot1) hp1=tot1; if(hp1==29) tot1+=1; else if(hp1==30) tot1+=0; else tot1+=2; hp1-=att[x1]; if(hp1>30) hp1=30; } tot2-=cnt; if(tot2<=0){ return 1; } if(x2<=2) tot1-=att[x2]; else if(x2==3) tot2-=att[x2]; else{ if(hp2>tot2) hp2=tot2; if(hp2==29) tot2+=1; else if(hp2==30) tot2+=0; else tot2+=2; hp2-=att[x2]; if(hp2>30) hp2=30; } return 2; } int main() { int t; cin>>t; while(t--){ scanf("%d%d%d",&x1,&hp1,&de1); scanf("%d%d%d",&x2,&hp2,&de2); int cnt=0; int w=99999; tot1=hp1+de1; tot2=hp1+de2; while(hp1>0&&hp2>0){ ++cnt; w=attack(cnt); if(w==0){ cout<<"NO"<<endl; break; } else if(w==1){ cout<<"YES"<<endl; break; } } } return 0; }