lahlahblog喵~

luogu P3185 [HNOI2007]分裂游戏

lahlah·2022-02-16 15:34·27 次阅读

luogu P3185 [HNOI2007]分裂游戏

https://www.luogu.com.cn/problem/P3185

把每个碗里的状态全部记下来显然是不现实的,分析一下发现可以把每个豆子看作一个独立的游戏

然后就变成相当于要将i移动到n,这个反过来跑个SG函数即可

按照SG函数的定理做就好了

好像就是MultiSG

具体可以参考代码

code;

Copy
#include<bits/stdc++.h> #define N 200050 using namespace std; int n, t, a[N], sg[N], vis[N]; void solve() { scanf("%d", &n); for(int i = 1; i <= n; i ++) scanf("%d", &a[i]); int ans = 0; for(int i = 1; i <= n; i ++) if(a[i] & 1) ans ^= sg[n - i]; if(!ans) printf("-1 -1 -1\n0\n"); else { int gs = 0, ansi = 0, ansj = 0, ansk = 0; for(int i = 1; i <= n; i ++) for(int j = i + 1; j <= n; j ++) for(int k = j; k <= n; k ++) { if((sg[n - i] ^ sg[n - j] ^ sg[n - k] ^ ans) == 0) {//判断先选了i,j,k后剩下的是不是必败态 gs ++; if(gs == 1) ansi = i, ansj = j, ansk = k; } } printf("%d %d %d\n%d\n", ansi - 1, ansj - 1, ansk - 1, gs); } } int main() { // freopen("a.out","w",stdout); for(int i = 1; i <= 21; i ++) { // 预处理SG函数 for(int j = 0; j <= 114514; j ++) vis[j] = 0; for(int j = 0; j < i; j ++) for(int k = j; k < i; k ++) vis[sg[j] ^ sg[k]] = 1; for(int j = 0; j <= 114514; j ++) if(!vis[j]) { sg[i] = j; break; } } scanf("%d", &t); while(t --) solve(); return 0; }
posted @   lahlah  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
历史上的今天:
2020-02-16 数学初联杂题乱讲
点击右上角即可分享
微信分享提示