博弈问题Hakase and Nano

Problem C. Hakase and Nano
Hakase and Nano are playing an ancient pebble game (pebble is a kind of rock). There are n packs of pebbles, and the i-th pack contains ai pebbles. They take turns to pick up pebbles. In each turn, they can choose a pack arbitrarily and pick up at least one pebble in this pack. The person who takes the last pebble wins. This time, Hakase cheats. In each turn, she must pick pebbles following the rules twice continuously. Suppose both players play optimally, can you tell whether Hakase will win?
Input The first line contains an integer T (1 ≤ T ≤ 20) representing the number of test cases. For each test case, the first line of description contains two integers n(1 ≤ n ≤ 106) and d (d = 1 or d = 2). If d = 1, Hakase takes first and if d = 2, Nano takes first. n represents the number of pebble packs. The second line contains n integers, the i-th integer ai (1 ≤ ai ≤ 109) represents the number of pebbles in the i-th pebble pack.
Output For each test case, print “Yes” or “No” in one line. If Hakase can win, print “Yes”, otherwise, print “No”.
Example
standard input standard output
2

3 1

1 1 2

3 2

1 1 2

Yes

No

这道博弈题不像我们之前做过的,有的博弈可以直接套公式加上简单的推理就可以很轻松的做出来,这道只能一步步的发现规律。

我们先从最简单的开始,H先手,先分析所有石堆都为1的情况,我们发现只有当石堆为3的倍数的情况H才必输。

现在H后手,N先拿。我们想,要让H必输,是不是N拿完之后保证所有石堆为1且堆数为3的倍数就可以了(上述情况)

从最简单的开始分析,所有石堆为1,当石堆为4,7,10....3n+1时,N拿走一个石堆就可以(1,1,1,1)

既然可以拿走一个石堆,那么那个石堆是不是可以不为1,有且只有一个石堆不为1,石堆个数为3n+1。(1,1,1,n)

当只有三堆石头,有且有一堆不为1,我们N拿完后剩1 (1,1,n)------(1,1,1)

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

int main()
{
    
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,d;
        scanf("%d%d",&n,&d);
        int i;
        int flag1=0;
        for(i=0;i<n;i++){
            scanf("%d",&a);
            if(a==1) flag1++;
        }
       
        if(d==2){
            if(n%3==0&&flag1==n-1){
                printf("No\n");
                continue;

            }
            if(n%3==1){
                if(flag1==n||flag1==n-1){
                    printf("No\n");
                    continue;

                }


            }
            printf("Yes\n");
        }
        if(d==1){
            if(n%3==0&&flag1==n){
                printf("No\n");
                continue;

            }
            printf("Yes\n");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40620465/article/details/82012134
今日推荐