原创 疲劳炉石传说

“疲劳”传说

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

 

posted @ 2019-08-01 10:27  神之右大臣  阅读(274)  评论(0编辑  收藏  举报