小A取石子(牛客小白月赛13 )

版权声明:转载时 别忘了注明出处 https://blog.csdn.net/ZCY19990813/article/details/89277022

链接:https://ac.nowcoder.com/acm/contest/549/I
来源:牛客网
 

题目描述

小A也听说了取石子这个游戏,也决定和小B一起来玩这个游戏。总共有n堆石子,双方轮流取石子,每次都可以从任意一堆中取走任意数量的石子,但是不可以不取。规定谁先取完所有的石子就获胜。但是小A实在是太想赢了,所以在游戏开始之前,小A有一次机会,可以趁小B不注意的时候选择其中一堆石子拿走其中的k个,当然小A也可以选择不拿石子。小A先手。双方都会选择最优的策略,请问在这样的情况下小A有没有必胜的策略,如果有输出YES,否则就输出NO。

输入描述:

一行两个整数N,K,表示分别有N堆石子以及小A可以拿走的石子个数k。

接下来N个整数表示每一堆的石子个数aiai

输出描述:

一行一个结果表示小A是否有必胜策略,如果有则输出YES,否则输出NO。

示例1

输入

3 2
1 1 1

输出

YES

备注:

1≤n≤1e5,1≤ai≤1e5,0≤k≤1e5

思路:尼姆博弈 

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <string>
#include <deque>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <set>
#define MAX 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int M=5e6+10;
priority_queue <int,vector<int>,greater<int> > q;
ll a[M];
set <ll> se;
map <ll,ll> mp;
int main()
{
    ll n,k;
    ll sum = 0;
    ll maxx = -1;
    scanf("%lld %lld",&n,&k);
    for(ll i=0; i<n; i++){
        scanf("%lld",&a[i]);
        if(a[i] > maxx)
            maxx = a[i];
        sum = sum ^ a[i];
    }

    if(sum != 0)//不取k异或不为0一定胜
        cout << "YES" << endl;
    else{
        sum = sum ^ k;//从中减去k
        if(sum !=0 && k <= maxx)//取了k,异或不为0也能胜
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ZCY19990813/article/details/89277022
今日推荐