SDUT第一届ACM知识挑战赛Fire Emblem [You Will Win - Special Version]

本文介绍了一款名为“火焰之纹章”的SRPG游戏,重点解析了游戏中的战斗规则及玩家属性如何影响战斗结果。通过具体示例,文章详细说明了不同武器和防具对玩家实际攻击力、防御力及攻击速度的影响。

Fire Emblem [You Will Win - Special Version]

Time Limit: 1000MS Memory Limit: 65536KB

blablabla: 这题比赛时候打着玩也没看。。。。。。tan90°   其实卡完别的题没时间了  
看见有超时之后我以为这题不能用循环攻击做。。。竟然可以= =
昨天一晚上卡这个题   开始怀疑自己方法不对。。。今天照着题解改还是不对
从头开始看老师讲的。。 结果发现一个防具的字符串定义错了

于是照着题解改的对了  又简化了一下自己的 也对了
too naive
Problem Description

火焰之纹章 (Fire Emblem) 是 SRPG 游戏的巅峰之作,其严格的战场设定和复杂的战斗和剧情系统,使得游戏的难度相当高。
从 1990 年至今,游戏共在各个游戏平台推出了十多部作品,都相当的受欢迎。

3744

 

我们来简化一下游戏系统,bLue 和 Stone 两人对战,每人有攻(初始攻击力)、防(初始防御力)、速(初始攻击速度)、血(生命值)4 个属性,并且都会携带一把武器和一件防具。

武器有 2 种属性:攻击力加成和重量。

防具有 2 种属性:防御力加成和重量。

玩家的实际攻击力 = 初始攻击力 + 武器攻击力加成。

玩家的实际防御力 = 初始防御力 + 防具防御力加成。

玩家的实际攻击速度 = 初始攻击速度 - 武器重量 - 防具重量。

玩家可用的武器和防具及其属性如下表(允许双方使用相同的武器和防具):

 

类型名称属性加成重量
武器DevineRapier105
武器InfinityBlade2525
武器TheSwordOfPBH5010
防具Immortal155
防具Ragnarok2525
防具HuaJiShield501

 

当游戏开始时,两人轮流发起战斗(如果某人的攻击速度小于等于 0 ,则他将无法发起战斗),每场战斗的规则为:
攻方先攻击一次,守方接着再攻击一次。攻击速度快的人可以在本轮战斗结束时额外再攻击一次(攻击速度相等时不存在额外攻击)。

伤害计算公式:伤害 = 自己的攻击力 - 对方的防御力(伤害小于等于 0 时均视为 0)。

在任何一次攻击结束后,如果被攻击者的生命值小于等于 0,则他将立即输掉游戏。

 

鉴于游戏的设定为蓝方先手,那么 bLue 当然要先攻击了。我们的问题就是,他们两人究竟谁会获得胜利呢?

Input

输入数据有多组(数据组数不超过 100),到 EOF 结束。
每组输入两行数据:

  • 第一行输入 4 个整数和 2 个字符串,分别代表 bLue 的攻、防、速、血、武器、防具;
  • 第二行输入 4 个整数和 2 个字符串,分别代表 Stone 的攻、防、速、血、武器、防具。

所有整数数值都在 [1, 100] 范围内,字符串不含空格且长度最大为 13 。

Output

每组输出占一行,若 bLue 赢,输出 "bLue wins!";若 Stone 赢,输出 "Stone wins!";若无法分出胜负(两人都无法发动战斗或两人都无法对对方造成伤害),则输出 "bLue Stone have to give up!"(输出均不包含引号)。

Example Input
30 5 25 30 DevineRapier Immortal
20 5 40 30 DevineRapier Ragnarok
Example Output
bLue wins!
Hint

对第 1 组示例的解释:

bLue 的属性为:攻击力:40,防御力:20,攻击速度:15,可以造成的伤害:10。
Stone 的属性为:攻击力:30,防御力:30,攻击速度:10,可以造成的伤害:10。

 

bLue 的攻击速度高,所以他每轮战斗结束时都会额外攻击一次。

战斗过程(b 表示 bLue,S 表示 Stone,→ 表示攻击,hp1 表示 bLue 的生命值,hp2 表示 Stone 的生命值):

 

Battle 1:

b→S hp2: 30-10=20
S→b hp1: 30-10=20
b→S hp2: 20-10=10(额外攻击)

 

Battle 2:

S→b hp1: 20-10=10
b→S hp2: 10-10=0

 

对于本题输入输出中所涉及的字符串,建议将其复制粘贴到你的代码中,以避免拼写错误。

Author
「山东理工大学第一届ACM知识挑战赛(机试)」不得不放弃、

我的代码:
思路:算出各自击败对方所需要的次数  比较次数
 攻速相同时 谁的次数小谁赢   如果次数相等且是偶数的话  Stone赢 否则bLue赢
攻速不同时,分两种情况
1.bLue的攻速高  则攻击顺序为
  b S b               S b  b     b S b
易比较得出如果
t1>=2*t2
那么bLue 就输了 
第二种情况同理
#include <bits/stdc++.h>
using namespace std;
struct node
{
    int att,def,v,hp;
    int attack;
} x[2];
char w1[15]= {"DevineRapier"}; //10     5
char w2[15]= {"InfinityBlade"}; // 25  25
char w3[15]= {"TheSwordOfPBH"}; //50   10
char f1[15]= {"Immortal"}; //15         5
char f2[15]= {"Ragnarok"}; // 25       25
char f3[15]= {"HuaJiShield"}; // 50        1 //就是这个字符串和上边的相同了。。
int main()
{
    int i,j;
    int n,m;
    char wep[2][20],defen[2][20];
    while(scanf("%d%d%d%d%s%s",&x[0].att,&x[0].def,&x[0].v,&x[0].hp,wep[0],defen[0])!=EOF)
    {
        int flag=1;
        scanf("%d%d%d%d%s%s",&x[1].att,&x[1].def,&x[1].v,&x[1].hp,wep[1],defen[1]);
        for(i=0; i<2; i++)
        {
            if(strcmp(w1,wep[i])==0)
            {
                x[i].att+=10;
                x[i].v-=5;
            }
            else if(strcmp(w2,wep[i])==0)
            {
                x[i].att+=25;
                x[i].v-=25;
            }
            else if(strcmp(w3,wep[i])==0)
            {
                x[i].att+=50;
                x[i].v-=10;
            }
            if(strcmp(f1,defen[i])==0)
            {
                x[i].def+=15;
                x[i].v-=5;
            }
            else if(strcmp(f2,defen[i])==0)
            {
                x[i].def+=25;
                x[i].v-=25;
            }
            else if(strcmp(f3,defen[i])==0)
            {
                x[i].def+=50;
                x[i].v-=1;
            }
        }
        x[0].att=max(0,x[0].att-x[1].def);
        x[1].att=max(0,x[1].att-x[0].def);
        int t1,t2;
        if(x[0].att==0) t1=999999;
        else if(x[1].hp%x[0].att==0)
        {
            t1=x[1].hp/x[0].att;
        }
        else  t1=x[1].hp/x[0].att+1;

        if(x[1].att==0) t2=999999;
        else if(x[0].hp%x[1].att==0)
        {
            t2=x[0].hp/x[1].att;
        }
        else  t2=x[0].hp/x[1].att+1;
        if(x[0].v <= 0 && x[1].v <= 0)
        {
            printf("bLue Stone have to give up!\n");
            continue;
        }
        else
        {
            if(x[0].v <= 0 ) t1=999999;
            if(x[1].v <= 0 ) t2=999999;
            if(t1 == t2 && t2 == 999999)
            {
                printf("bLue Stone have to give up!\n");
                continue;
            }
            if(x[0].v == x[1].v)
            {
                if(t1 > t2)
                {
                    flag=0;
                }
                else if(t1==t2)
                {
                    if(t1%2==0)
                    {
                        flag=0;
                    }
                }
            }
            else if(x[0].v>x[1].v)
            {
                if(t1>=2*t2)
                {
                    flag=0;
                }
            }
            else if(x[0].v<x[1].v)
            {
                if(2*t1<=t2)
                {
                    flag=1;
                }
                else  flag=0;
            }
        }
        if(flag==1)
        {
            printf("bLue wins!\n");
        }
        else if(flag==0)
        {
            printf("Stone wins!\n");
        }
    }
    return 0;
}


照着题解改的代码:

#include <bits/stdc++.h>
using namespace std;
struct node
{
    int att,def,v,hp;
    int attack;
} x[2];
char w1[15]= {"DevineRapier"}; //10     5
char w2[15]= {"InfinityBlade"}; // 25  25
char w3[15]= {"TheSwordOfPBH"}; //50   10
char f1[15]= {"Immortal"}; //15         5
char f2[15]= {"Ragnarok"}; // 25       25
char f3[15]= {"HuaJiShield"}; // 50        1
int main()
{
    int i,j;
    int n,m;
    char wep[2][20],defen[2][20];
    while(scanf("%d%d%d%d%s%s",&x[0].att,&x[0].def,&x[0].v,&x[0].hp,wep[0],defen[0])!=EOF)
    {
        int flag=1;
        scanf("%d%d%d%d%s%s",&x[1].att,&x[1].def,&x[1].v,&x[1].hp,wep[1],defen[1]);
        for(i=0; i<2; i++)
        {
            if(strcmp(w1,wep[i])==0)
            {
                x[i].att += 10;
                x[i].v -= 5;
            }
            else if(strcmp(w2,wep[i])==0)
            {
                x[i].att += 25;
                x[i].v -= 25;
            }
            else if(strcmp(w3,wep[i])==0)
            {
                x[i].att += 50;
                x[i].v -= 10;
            }
            if(strcmp(f1,defen[i])==0)
            {
                x[i].def += 15;
                x[i].v -= 5;
            }
            else if(strcmp(f2,defen[i])==0)
            {
                x[i].def += 25;
                x[i].v -= 25;
            }
            else if(strcmp(f3,defen[i])==0)
            {
                x[i].def += 50;
                x[i].v -= 1;
            }
        }
        x[0].att=max(0, x[0].att-x[1].def);
        x[1].att=max(0, x[1].att-x[0].def);
        if(x[0].v<=0 && x[1].v<=0)
        {
            printf("bLue Stone have to give up!\n");
        }
        else
        {
            if(x[0].v<=0) x[0].att=0;
            if(x[1].v<=0) x[1].att=0;
            if(x[0].att==0 && x[1].att==0)
            {
                printf("bLue Stone have to give up!\n");
                continue;
            }
            int f=1;
            while(x[0].hp>0 && x[1].hp>0)
            {
                if(f==1)
                {
                    x[1].hp -= x[0].att;
                    if(x[1].hp <= 0) break;
                    x[0].hp -= x[1].att;
                    if(x[0].hp <= 0) break;
                }
                if(f==-1)
                {
                    x[0].hp -= x[1].att;
                    if(x[0].hp <= 0) break;
                    x[1].hp -= x[0].att;
                    if(x[1].hp <= 0) break;
                }
                if(x[0].v > x[1].v)
                {
                    x[1].hp -= x[0].att;
                    if(x[1].hp <= 0) break;
                }
                if(x[0].v < x[1].v)
                {
                    x[0].hp -= x[1].att;
                    if(x[0].hp <= 0) break;
                }
                f*=-1;
            }
            if(x[0].hp<=0) printf("Stone wins!\n");
            if(x[1].hp<=0) printf("bLue wins!\n");
        }
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值