HDU - 3951 - Coin Game(nim博弈)

After hh has learned how to play Nim game, he begins to try another coin game which seems much easier.

The game goes like this:
Two players start the game with a circle of n coins.
They take coins from the circle in turn and every time they could take 1~K continuous coins.
(imagining that ten coins numbered from 1 to 10 and K equal to 3, since 1 and 10 are continuous, you could take away the continuous 10 , 1 , 2 , but if 2 was taken away, you couldn’t take 1, 3, 4, because 1 and 3 aren’t continuous)
The player who takes the last coin wins the game.
Suppose that those two players always take the best moves and never make mistakes.
Your job is to find out who will definitely win the game.
Input
The first line is a number T(1<=T<=100), represents the number of case. The next T blocks follow each indicates a case.
Each case contains two integers N(3<=N<=10 9,1<=K<=10).
Output
For each case, output the number of case and the winner “first” or “second”.(as shown in the sample output)
Sample Input
2
3 1
3 2
Sample Output
Case 1: first
Case 2: second

若干硬币围成一个环,两个人取硬币,只能取连续的,最后取完的获胜。一个Nim博弈的题目。
当k >= n的时候,先手一定赢,一次就取完了。
n > k: n为偶数的时候,后手一定输,因为先手取走一部分之后,环状变成了链状,后手可以在剩下的连续硬币中间选取一些硬币使得两边硬币数量相同,即实现均分。这样就形成了(n, n)的奇异棋局,面对这一局面的人一定会输的,因为只能取连续的,所以只能从一边选取,后手只要保证对称着和先手一样的取法一定会获胜。
n为奇数的时候,k等于1的时候,先手一定赢,否则还可以按照上面的方法,构造奇异棋局使得后手必赢。
AC代码:

#include <cstdio>
#include <cstring>
using namespace std;

int main()
{
    int n, k, t;
    scanf("%d", &t);
    for(int test = 1; test <= t; test++)
    {
        scanf("%d%d", &n, &k);
        printf("Case %d: ", test);
        if(k >= n)
        {
            printf("first\n");
            continue ;
        }
        if(n % 2 == 0)
        {
            printf("second\n");
            continue ;
        }
        if(k == 1)  printf("first\n");
        else    printf("second\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40788897/article/details/82850028