趣味ACM题 圣骑士的斩杀

来源:互联网 发布:android 冷启动优化 编辑:程序博客网 时间:2024/04/27 14:27

趣味ACM题 圣骑士的斩杀

最近一张山东省的ACM试卷在网上广为流传,道题目是根据暴雪著名游戏炉石传说来设计的,是计算在一局游戏中死鱼骑是否能一回合斩杀对手。下面是我个人的解答,如有不严谨之处,欢迎指正!

试卷照片

目录

  • 趣味ACM题 圣骑士的斩杀
    • 目录
    • 题目描述
    • 题目分析
    • 示例代码
    • 运行结果

题目描述

题目描述较长,没玩过炉石传说的小伙伴可能第一时间看不太懂,不过没关系,可以先看后面的题目分析,有需要的时候再倒回来看题目描述。

鱼人是炉石里的一支强大种族,在探险者协会里,圣骑士有了一张新牌,叫亡者归来,效果是召唤本轮游戏中7个已死的鱼人。如果死掉的不足7个,那么召唤的数量就会不足7个。
鱼人有很多,下面的4个是:
寒光智者:3费用 2攻击 2血量 战吼:每个玩家抽两张牌。
鱼人领军:3费用 3攻击 3血量 所有其他鱼人攻击+2,血量+1。
蓝腮战士:2费用 2攻击 1血量 冲锋。
老瞎眼:4费用 2攻击 4血量 冲锋,每有一个其他鱼人在场就增加一点攻击。
下面给一些说明:
费用:召唤随从的消耗,技能效果召唤的随从不消耗额外的费用,只会消耗卡牌本身的费用,双方玩家最多拥有10点费用。
攻击:随从每次能够造成的伤害。
战吼:拥有战吼的随从,在从手牌里打出时会触发这个效果,被技能召唤的随从不会触发战吼效果。
冲锋:本来,在召唤出来的这一轮,随从是无法攻击的,但是有冲锋就可以,召唤回合可以直接攻击。
战场:游戏盘,游戏内各种内容发生的地方,每场游戏都发生在棋盘上

现在该你出牌了,你有10点法力,只剩下一张亡者归来。战场上没有任何随从,意味着你的随从可以直接攻击对手英雄。你还记得你出过的鱼人,也知道对手英雄的血量,那你能够用手上唯一这一张牌赢得胜利吗?
输入:
多种测试方案,第1行的整数表示测试数量(小于等于22000)
每个测试的第1行都包括2个整数n(已死鱼人0<=n<=7),h(对手英雄血量 0<h<30)
后续N行里,每行都包括字符串,表示已死鱼人名称,字符串只能为:”寒光智者”,”鱼人领军”,”蓝腮战士”,”老瞎眼”。
输出:
列出所有方案后,如果能赢得游戏,那么就输出”呜啦啦啦啦呱啦哈哈!”,否则输出”跟你说个笑话,圣骑士的斩杀”。使用随从攻击对方英雄,使其血量少于等于0即可胜利。
示例(注意:Coldlight Oracle,Murloc Warleader, Bluegill Warrior, Old Murk-Eye 分别是 寒光智者,鱼人领军,蓝腮战士,老瞎眼):

这里写图片描述

题目分析

题目描述很长,但只要找到关键点很容易就做出来了。由于召唤出来的鱼人只有具备冲锋属性的才能在本回合进行攻击,所以我们只需要考虑蓝腮战士和老瞎眼的能够造成的伤害。从而我们将题目转化为比较两个整数的大小,一是敌方英雄的血量,二是蓝腮战士数量*蓝腮战士攻击与老瞎眼数量*老瞎眼攻击的总和。而蓝腮战士的攻击等于2点自身攻击加上每个鱼人领军提供的2点额外攻击,老瞎眼的攻击等于2点自身攻击加上每个鱼人领军提供的2点额外攻击再加上除自身以外每有一个其他鱼人在场提供的1点攻击。
分析到这里,题目就已经算是解答出来了,剩下的也就只是考察代码的基本功了。

示例代码

#include <iostream>#include <vector>using namespace std;int main(int argc, const char * argv[]) {    unsigned testCount = 0;    while (testCount == 0 || testCount >= 22000) {        cout << "请输入测试数量(1~22000):" << endl;        cin >> testCount;    }    //初始化记录是否斩杀的vector对象    vector<bool> isExecutes(testCount,0);    while (testCount > 0) {        unsigned n = 0, h = 0;        while (n > 7 || (h == 0 || h > 30)) {            cout << "请输入已死鱼人数量(0~7)和敌方英雄血量(1~30)" << endl;            cin >> n >> h;        }        unsigned coldLightOracleCount = 0, murlocWarLeaderCount = 0, blueGillWarriorCount = 0, oldMurkEyeCount = 0, totalMurlocCount = n;        cout << "请输入已死鱼人的名字(寒光智者 鱼人领军 蓝腮战士 老瞎眼)" << endl;        while (n > 0) {            string murlocName = "";            cin >> murlocName;            if (murlocName == "寒光智者") {                ++coldLightOracleCount;            }            else if (murlocName == "鱼人领军") {                ++murlocWarLeaderCount;            }            else if (murlocName == "蓝腮战士") {                ++blueGillWarriorCount;            }            else if (murlocName == "老瞎眼") {                ++oldMurkEyeCount;            }            else{                cout << "输入有误,请重新输入" << endl;                continue;            }            --n;        }        unsigned damage = blueGillWarriorCount * (2 + murlocWarLeaderCount * 2) + oldMurkEyeCount * (2 + murlocWarLeaderCount * 2 + totalMurlocCount - 1);        //如果总伤害大于地方英雄血量,则将对应的可斩杀标志改为1        if (damage >= h) {            isExecutes[isExecutes.size() - testCount] = 1;        }        --testCount;    }    for (auto isExecute : isExecutes) {        if (isExecute) {            cout << "呜啦啦啦啦呱啦哈哈!" << endl;        }        else{            cout << "跟你说个笑话,圣骑士的斩杀" << endl;        }    }    return 0;}

运行结果

请输入测试数量(1~22000):3请输入已死鱼人数量(0~7)和敌方英雄血量(1~30)3 1请输入已死鱼人的名字(寒光智者 鱼人领军 蓝腮战士 老瞎眼)寒光智者寒光智者鱼人领军请输入已死鱼人数量(0~7)和敌方英雄血量(1~30)3 8请输入已死鱼人的名字(寒光智者 鱼人领军 蓝腮战士 老瞎眼)老瞎眼老瞎眼寒光智者请输入已死鱼人数量(0~7)和敌方英雄血量(1~30)7 30请输入已死鱼人的名字(寒光智者 鱼人领军 蓝腮战士 老瞎眼)老瞎眼蓝腮战士蓝腮战士鱼人领军鱼人领军寒光智者寒光智者跟你说个笑话,圣骑士的斩杀呜啦啦啦啦呱啦哈哈!跟你说个笑话,圣骑士的斩杀Program ended with exit code: 0
1 0
原创粉丝点击