(AcWing) Split-Nim Games

Given n piles of stones, two players take turns to operate, each operation can take away one pile of stones, and then put in two piles of smaller stones (the size of the new pile can be 0, and the total number of stones in the two new piles can be greater than the pile of stones taken away), and those who are unable to operate in the end are deemed to have failed.

Ask whether the first player will win if both players adopt the optimal strategy.

input format

The first line contains the integer n.

The second line contains n integers, where the i-th integer represents the number ai of the i-th pile of stones.

output format

If the first player wins, then output  Yes.

Otherwise, output  No.

data range

1≤n,ai≤100

Input sample:

2
2 3

Sample output:

Yes
#include<iostream>
#include<unordered_set>
#include<cstring>
using namespace std;

const int N = 110;
int f[N]; //记录每个状态的sg

int sg(int x)
{
    if(f[x]!=-1) return f[x];
    
    unordered_set<int> S;
    
    //列举出每堆石子可以分成哪几种比它小的两堆石子
    for(int i=0;i<x;i++){
        for(int j=0;j<=i;j++){
            //定理:sg(i,j) = sg(i)^sg(j)
            S.insert(sg(i)^sg(j));
        }
    }
    
    for(int i=0;;i++) if(!S.count(i)) return f[x] = i;
}

int main()
{
    int n;
    cin>>n;
    
    int res = 0;
    
    memset(f,-1,sizeof f);
    
    for(int i=0;i<n;i++)
    {
        int num;
        cin>>num;
        res^=sg(num);
    }
    
    if(res) cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
    
}

 

Guess you like

Origin blog.csdn.net/GF0919/article/details/132007496
Recommended