博弈论 P1247 取火柴游戏
题目大意:
给出n堆石子,每次操作只可以在同一堆石子里面取若干个石子,取走最后一颗的人获胜。
P1247 取火柴游戏
我的做法是:
这题是博弈论里面比较经典的模型:Nim博弈
有没学过的可以直接点以下链接
董晓老师的
结论就是如果异或和为零的话,那就是必败态,否则就是必胜态。
因为每个必胜态都可以制造一个必败态给对手;而每一个必败态,无论走哪一步,都会把必胜态留给别人。
必胜态为什么可以制造出必败态呢?
它需要制造的状态是所有异或和都为零的状态:
把异或和再异或自己一遍,会得到其余数字的异或和。
那对于ai要变成的状态,就是剩余数字的异或和,这样子整体的异或和就为0。
所以只需要再加一步判断它要变成的数字有没有比自身还要大:如果比自身还要大的话,显然是不行的,否则就是可以的。
using namespace std;
const int N = 5e5+100;
#define int long long
int n,sum = 0;
int a[N];
signed main()
{
cin>>n;
for(int i = 1 ; i <= n ; ++i)
cin>>a[i],sum^=a[i];
if(sum == 0){
cout<<"lose\n";return 0;
}
for(int i = 1 ; i <= n ; ++i)
{
if((sum^a[i]) < a[i]){
cout<<a[i] - (sum^a[i])<<" "<<i<<endl;
for(int j = 1 ; j <= n ; ++j)
{
if(j == i)cout<<(sum^a[i])<<" ";
else cout<<a[j]<<" ";
}
return 0;
}
}
return 0;
}
浙公网安备 33010602011771号