有什么逻辑错误

0

题目地址:https://oj.neauacm.cn/problem.php?id=1180

题目描述

黑大帅和潇洒哥在玩游戏,他们找到n行石子,每行有m颗石子,现在游戏规则是这样的,每个人轮流拿,每次只能拿一行中的一个或连续两个,最后谁拿不了谁输,为了展现绅士风范,潇洒哥让黑大帅先拿。

输入
输入包含多组数据。
输入的第一行为一个整数t(1<=t<=1000),代表测试用例的组数。
接下来的t组测试用例按照如下格式给出: 
每组数据占一行,包含两个整数n,m(1<=n<=5000,1<=m<=10^16)。

输出
对于每一组测试用例,在新的一行中,如果黑大帅能赢,输出“Black Marshal”,否则输出“Chic brother”,不包含引号。

样例输入
2
1 1
2 3
样例输出
Black Marshal
Chic brother

#include <stdio.h>

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        long long  n,m;
        scanf("%lld%lld", &n,&m);
        if(m==1)
        {
            if(n%2==0)
            {
                printf("Chic brother\n");
            }
            else
            {
                printf("Black Marshal\n");
            }
        }
        else if(m%3==0||n%3==0)
        {
            printf("Chic brother\n");
        }
        else
        {
            printf("Black Marshal\n");
        }
    }
    return 0;
}
ava
婆罗摩笈多

2023-10-22

悬赏金额:¥5元

1. 回答问题后,可以看到提问者联系方式。

2. 如果对问题有不明确的地方,可以在回复中写下你的疑问,就可以看到提问者的联系方式,然后详细沟通。

3. 如果私下沟通解决了问题,建议回答者将解决方案补充到本站,提问者勾选正确答案。每个人回答的问题数量,是能力的象征。

4. 回答问题后,可以通过提问者的联系方式私下协商领取悬赏的方式,本站不做任何干涉,不做担保,不抽取佣金,请双方谨慎操作。

1

第一个if逻辑没有问题,当m为1是,只要行数是奇数就是黑大帅赢,否则就是潇洒哥赢

if(m==1)
        {
            if(n%2==0)
            {
                printf("Chic brother\n");
            }
            else
            {
                printf("Black Marshal\n");
            }
        }

if之后的else逻辑存在遗漏,当m%3==0时,则代表先手必输,因为每一行都是黑大帅先手,然后以潇洒哥结束,潇洒哥赢。

当m%3 !=0时则

奇数行时,每一行以黑大帅先手,黑大帅结束,黑大帅赢,

偶数行时,每一行以潇洒哥先手,潇洒哥结束,潇洒哥赢。

 else if(m%3==0)
 {
	printf("Chic brother\n"); 
 }else {
	if(n%2==0) 
	{
		printf("Chic brother\n"); 		 	 
	}
	else
	{
		printf("Black Marshal\n");	
	}		
	
 }
        

-------------------分割线-上面是错误的逻辑--------------------------------

首先有一个重要的要素便是这道题中,先后手拿石子不局限于在同一行,即当有两行的情况下,黑大帅先在第一行拿了石子,那么潇洒哥可以在第一行,也可以在第二行拿去石子。

所以上述的逻辑便行不通了(只有当上述的行数为1时,行得通)。

上述的逻辑是通过巴什博弈进行推演的出来的。

相关知识点如下:https://baike.baidu.com/item/%E5%B7%B4%E4%BB%80%E5%8D%9A%E5%BC%88/1819345?fr=ge_ala

按照上述条件,应该根据尼姆博弈,来确定最后的赢家是谁
相关知识点如下:https://baike.baidu.com/item/%E5%B0%BC%E5%A7%86%E5%8D%9A%E5%BC%88/58986985?fr=ge_ala

根据尼姆博弈,可以得知,当算出尼姆和之后,根据尼姆和是否为0,便可以得知赢家是谁。当尼姆和为0是,后手方必赢,即潇洒哥赢,反之则先手方黑大帅赢。

而因为这道题的中,n代表行数,m代表每行中石子的个数。由此可得,石子的个数在每一行都是一样的,根据尼姆和的求法可以得出,这道题的尼姆和是否为0只需要判断行数的奇偶。

当行数为奇数行时,尼姆和不为0,先手赢;当行数为偶数行时,尼姆和为0,后手赢。

具体代码如下

#include <stdio.h>
       
int main()
{
    int t;
    scanf("%d",&t);

    while(t--)
    {
        long long  n,m;
        scanf("%lld%lld", &n,&m);
		// 当行数为1时,使用巴什博弈
        if (n == 1) {
            if (m % 3 == 0) 
            {
                printf("Chic brother\n");
            }
            else
            {
                printf("Black Marshal\n");
            }
        }
		// 当行数>1时,使用尼姆博弈
		else
        {
            if( n % 2 == 0 )
            {
                  
                printf("Chic brother\n");
            }
            else
            {
                printf("Black Marshal\n");
            } 
        }
    }
    return 0;
}
ava

2023-10-24

0

#include <stdio.h>

int main()

{

    int t;

    scanf("%d", &t);

    

    while (t--)

    {

        long long n, m;

        scanf("%lld %lld", &n, &m);

        

        if (m == 1) // 如果m等于1,根据规则判断谁能赢

        {

            if (n % 2 == 0)

            {

                printf("Black Marshal\n");

            }

            else

            {

                printf("Chic brother\n");

            }

        }

        else if (m % 3 == 0 || (n % 3 == 0 && m % 2 == 0)) // 如果m是3的倍数或者(n是3的倍数且m是偶数),潇洒哥能赢

        {

            printf("Chic brother\n");

        }

        else

        {

            printf("Black Marshal\n");

        }

    }

    

    return 0;

}

技术讨论社区
相关提问