博弈论 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;
}
posted on 2025-08-19 20:31  钟一一  阅读(24)  评论(0)    收藏  举报