luogu P3185 [HNOI2007]分裂游戏
https://www.luogu.com.cn/problem/P3185
把每个碗里的状态全部记下来显然是不现实的,分析一下发现可以把每个豆子看作一个独立的游戏
然后就变成相当于要将移动到,这个反过来跑个函数即可
按照函数的定理做就好了
好像就是
具体可以参考代码
code;
#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;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
2020-02-16 数学初联杂题乱讲