HDU 3389 Game 阶梯博弈

本文介绍了一个具体的策略游戏问题,通过分析游戏规则和可能的操作路径,提出了一个有效的解决方案。重点在于利用数学方法简化游戏过程,并通过NIM游戏理论来预测游戏胜负。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Game

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 46 Accepted Submission(s): 42
 
Problem Description
Bob and Alice are playing a new game. There are n boxes which have been numbered from 1 to n. Each box is either empty or contains several cards. Bob and Alice move the cards in turn. In each turn the corresponding player should choose a non-empty box A and choose another box B that B<A && (A+B)%2=1 && (A+B)%3=0. Then, take an arbitrary number (but not zero) of cards from box A to box B. The last one who can do a legal move wins. Alice is the first player. Please predict who will win the game.
 
Input
The first line contains an integer T (T<=100) indicating the number of test cases. The first line of each test case contains an integer n (1<=n<=10000). The second line has n integers which will not be bigger than 100. The i-th integer indicates the number of cards in the i-th box.
 
Output
For each test case, print the case number and the winner's name in a single line. Follow the format of the sample output.
 
Sample Input
2
2
1 2
7
1 3 3 2 2 1 2
 
Sample Output
Case 1: Alice
Case 2: Bob
 
Author
题目大意:

B<A && (A+B)%2=1 && (A+B)%3=0.    选择两个盒子,若  A  B  满足这个关系,则能将  A  中转移任意个卡片到  B  中。
不能转移就输了。

思路:

我们首先打个表,观察  盒子可以如何转移。

    int mapp[20][20]={0};
    for(int i=1;i<20;i++)
    {
        int work=0;
        for(int j=1;j<i;j++)
        {
            if((i+j)%2==1&&(i+j)%3==0)
            {
                mapp[i][j]=1;
            }
            else
            {

            }
        }
    }
    for(int i=1;i<20;i++)
    {
        for(int j=1;j<20;j++)
            if(mapp[i][j])
                cout<<i<<" "<<j<<endl;
    }

然后我们发现,盒子  1   3   4   都是不能转移的盒子,也就是说是转移的终点。
对于  某个盒子,转移到最后,他的步数要么全是偶数,要么全是奇数,打出表来就可以观察到的。
这样的话可以转化到阶梯博弈上来了,我们只需要NIM 这些奇数步转移的盒子就可以的到答案。
为什么对于偶数步的盒子我们可以不用管呢?   下面给出我的一些证明:

如果对于当前的状态,(所有奇数步盒子   nim   得到答案是   必胜)
那么我们按照必胜的步骤来移动奇数步盒子,如果对手移动奇数步盒子,那么我们继续按照必胜步骤移动。
如果对手移动偶数步盒子,那么我们就将对手移动的这些卡片移动到下一个盒子里,也就是保持原先的状态。这样走下去,结果一定是之前判断得到的答案。

AC代码:

#include <iostream>  
#include <string.h>  
#include <stdio.h>  
  
using namespace std;  
  
int main()  
{  
    int T,tt=1;  
    int n;  
    scanf("%d",&T);  
    while(T--)  
    {  
        scanf("%d",&n);  
        int ans = 0;  
        for(int i=1;i<=n;i++)  
        {  
            int x;  
            scanf("%d",&x);  
            if(i%6==0 || i%6==2 || i%6==5)  
                ans ^= x;  
        }  
        printf("Case %d: ",tt++);  
        if(ans) puts("Alice");  
        else puts("Bob");  
    }  
    return 0;  
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值