题目链接
前置trick:
使用vector去重:
vector<int> a(n);for(int i=0;i<n;i++) cin>>a[i];sort(a.begin(),a.end());a.erase(unique(a.begin(),a.end()),a.end());n=a.size();
题意:
有 n n n堆石子,第 i i i堆有 a i a_i ai颗。Alice 和 Bob 两人轮流,Alice 先手。每一轮玩家从所有非空堆中拿走相同数量的石子,不能行动的失败。若两位玩家均使用最优策略,求最终获胜者。
题解:
首先考虑如何简化问题,由于是从所有非空堆拿走石头,所以重复数量石头堆可以去重。然后最少的石头堆只有一个石头的情况下只有一种操作,即所有石头堆都取走一个石头,直到没有石头或最少数量大于1的情况。在新的情况下,考虑从所有石子堆中取出一颗石子的新状态为 S S S,若 S S S为必败态,则当前状态为必胜态。
否则, S S S的后继状态中必然存在必败态,记为 S ′ S^{\prime} S′。我们发现 S S S的后继状态集合包含在当前状态的后继状态集合中!这样,当前状态的后继集合中必然存在必败态,当前状态就是必胜态。(好像是结论)那么只需要一开始模拟完最小堆为1的情况即可。
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define db double
const int mod=1e9+7;
const int N=4e5;
const db PI=acos(-1);
int T,n;signed main()
{std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin>>T;while(T--){cin>>n;vector<int> a(n);for(int i=0;i<n;i++) cin>>a[i];sort(a.begin(),a.end());a.erase(unique(a.begin(),a.end()),a.end());n=a.size();int sum=0;for(int i=0;i<n;i++){if(a[i]!=i+1) break;sum++;}if(a[n-1]==n) sum++;cout<<((sum%2==0)?"Alice":"Bob")<<"\n";}
}