最后一击 - 比赛编程

时间:2015-03-17 22:22:47

标签: c

描述

安德烈和贝托正在玩一款以非常特别的方式奖励玩家的电脑游戏:只有最后一击击败怪物的玩家才能获得怪物留下的所有金币。这意味着,虽然其他玩家可能帮助击败了怪物,但只有那个给予最后一击的人才会得到奖励。

安德烈对这个系统很感兴趣,并请求你的帮助。考虑到怪物的生命点数,安德烈和贝托可能造成的伤害,以及两次连续攻击之间所需的准备时间,找出谁将最后击中怪物,击败它并获得奖励。

一开始,安德烈和贝托都会分别攻击,造成At和Bt伤害点。在每次攻击之后,安德烈和贝托都必须分别等待Ad和Bd秒,才能再次攻击。每当安德烈和贝托可以同时攻击时(如开始时),安德烈优先并首先进行攻击。当生命点的生命值小于或等于零时,怪物就会被击败。

输入

第一行包含一个整数T,表示要遵循的测试用例数。

每个测试用例以四个整数At,Ad,Bt和Bd(1≤At,Ad,Bt,Bd≤100)开始,分别表示安德烈和贝托两次连续攻击之间的攻击伤害和前置时间。

下面会有一个整数H(1≤H≤10000),表示怪物的生命点数。

输出

对于每个测试用例,打印一行包含一个名称,如果他是最后一个击中怪物,则为“Andre”,否则为“Beto”。

我的解决方案

#include <stdio.h>
#include <math.h>

int absolute(int x)
{
    return (x < 0) ? -x : x;
}
int main()
{
    int t;
    int i,j; //for loops
    scanf("%d",&t);
    for(i = 0; i < t; i++)
    {
        int att,ad,bt,bd;
        scanf("%d %d %d %d",&att,&ad,&bt,&bd);
        int h;
        scanf("%d",&h);

        int aux = 0;
        int dt = absolute(ad - bd);// time difference

        if(ad <= bd) //andre is faster ... So andre hits in every loop and beto waits for his turn
        {
            while(1)
            {
                h -= att; //andre hits
                if(h <= 0)
                {
                    printf("Andre\n");
                    break;
                }
                if(aux++ == dt)
                {
                    h -= bt;//beto hits
                    aux = 0;
                    if(h <= 0)
                    {
                        printf("Beto\n");
                        break;
                    }
                }
            }
        }
        else //beto is faster ... So beto hits in every loop and andre waits for his turn
        {
            while(1)
            {
                if(aux++ == dt) //first to hit is andre 
                {
                    h -= att; //andre hits
                    aux = 0;
                    if(h <= 0)
                    {
                        printf("Andre\n");
                        break;
                    }
                }
                h -= bt; //beto hits
                if(h <= 0)
                {
                    printf("Beto\n");
                    break;
                }
            }
        }
    }
    return 0;
}

这个解决方案给出了错误的回答......有人有提示吗?

1 个答案:

答案 0 :(得分:1)

以下是您失败的测试用例:

1
1 1 1 2
2

您的输出

Andre

我非常确定输出应该是......

Beto

我在您的代码中看到的问题

  • Andre和Beto都应该在第1轮攻击
  • 如果安德烈每第2轮攻击一次,并且Beto每第3轮攻击一次,你的攻击顺序就会不正确。

这里有一些工作代码:

#include <stdbool.h>
#include <stdio.h>
#include <math.h>

int main()
{
    int t;
    scanf("%d",&t);

    for(int i = 0; i < t; i++) {
        int at, ad, bt, bd, h;
        scanf("%d %d %d %d %d",&at, &ad, &bt, &bd, &h);

        int timestep = 0;
        while (true) {
            if (timestep % ad == 0) {
                h -= at;
            }
            if (h <= 0) {
                printf("Andre\n");
                break;
            }
            if (timestep % bd == 0) {
                h -= bt;
            }
            if (h <= 0) {
                printf("Beto\n");
                break;
            }
            timestep++;
        }
    }
}

让我们用python

做一些模糊测试
import subprocess
import random

def mine(inp):
    fd = subprocess.Popen("./mine", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    return fd.communicate(inp)[0]

def yours(inp):
    fd = subprocess.Popen("./yours", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    return fd.communicate(inp)[0]

def main():
    for i in range(100):
        inp = '1\n'
        inp += '{} {} {} {}\n'.format(random.randint(1, 100), random.randint(1, 100), random.randint(1, 100), random.randint(1, 100))
        inp += '{}\n'.format(random.randint(1, 1000))

        if mine(inp) != yours(inp):
            print inp.strip()
            print "My output:  ", mine(inp).strip()
            print "Your output:", yours(inp).strip()
            print

if __name__ == '__main__':
    main()

然后...

如果我们对我的程序输出有信心。我是谁,然后我们可以使用模糊测试程序来创建程序失败的随机输入:

1
73 73 98 1
44
My output:   Andre
Your output: Beto

1
17 44 66 55
420
My output:   Beto
Your output: Andre

1
53 30 58 9
18
My output:   Andre
Your output: Beto

1
5 22 49 31
405
My output:   Beto
Your output: Andre

1
50 37 51 43
591
My output:   Beto
Your output: Andre

1
24 44 96 84
655
My output:   Beto
Your output: Andre

1
59 100 12 37
516
My output:   Andre
Your output: Beto

1
97 35 79 42
508
My output:   Beto
Your output: Andre

1
30 48 82 56
419
My output:   Beto
Your output: Andre

1
26 45 22 16
279
My output:   Andre
Your output: Beto

1
51 91 62 42
427
My output:   Andre
Your output: Beto

1
90 9 34 16
229
My output:   Beto
Your output: Andre

1
90 61 31 19
789
My output:   Andre
Your output: Beto

1
87 41 43 38
503
My output:   Andre
Your output: Beto

1
89 60 76 29
613
My output:   Andre
Your output: Beto