博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj 1188 : [HNOI2007]分裂游戏 sg函数
阅读量:5144 次
发布时间:2019-06-13

本文共 1574 字,大约阅读时间需要 5 分钟。

 

给n个位置, 每个位置有一个小球。 现在两个人进行操作, 每次操作可以选择一个位置i, 拿走一个小球。然后在位置j, k(i<j<=k)处放置一个小球。 问你先进行什么操作会先手必胜以及方法数量。

 

感觉这题好神

如果一个位置有偶数个小球, 那么等价于这个位置没有小球。 因为第二个人可以进行和第一个人相同的操作。 所以初始值%2。

然后我们把每个位置看成一个状态, 如果i有一个小球, 等价于j, k 也有一个小球。 然后转移。

方法数量就n^3枚举就可以了。

#include 
using namespace std;#define mem1(a) memset(a, -1, sizeof(a))int sg[22], a[22], n;int mex(int x){ if(~sg[x]) return sg[x]; bool vis[1000]; memset(vis, 0, sizeof(vis)); for(int i = x + 1; i <= n; i++) { for(int j = i; j <= n; j++) { vis[mex(i)^mex(j)] = 1; } } for(int i = 0; ; i++) { if(!vis[i]) return sg[x] = i; }}int main(){ int t; cin>>t; while(t--) { cin>>n; for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); } mem1(sg); int ans = 0, cnt = 0; for(int i = 1; i <= n; i++) { if(a[i]&1) { ans ^= mex(i); } } int flag = 0; for(int i = 1; i <= n; i++) { for(int j = i + 1; j <= n; j++) { for(int k = j; k <= n; k++) { ans ^= mex(i)^mex(j)^mex(k); if(!flag && ans == 0) { printf("%d %d %d\n", i-1, j-1, k-1); flag = 1; } if(ans == 0) { cnt++; } ans ^= mex(i)^mex(j)^mex(k); } } } if(cnt != 0) cout<
<

 

转载于:https://www.cnblogs.com/yohaha/p/5927574.html

你可能感兴趣的文章
error: more than one device and emulator 问题解决
查看>>
Android Studio 编译不通过,报错“找不到org.apache.http
查看>>
springmvc集成Freemarke配置的几点
查看>>
Django 学习
查看>>
Linux-以指定用户运行redis
查看>>
Linux-socket的close和shutdown区别及应用场景
查看>>
xpath
查看>>
parted分区
查看>>
图片标签img
查看>>
JavaScript语言中文参考手册.chm
查看>>
表哥的Access入门++以Excel视角快速学习数据库知识pdf
查看>>
TC 配置插件
查看>>
关于异步reset
查看>>
索引优先队列的工作原理与简易实现
查看>>
并发编程简介
查看>>
基于K-近邻分类算法的手写识别系统
查看>>
使用easyui的form提交表单,在IE下出现类似附件下载时提示是否保存的现象
查看>>
PC站跳转M站的方法
查看>>
wow 各职业体验(pvp)
查看>>
Streaming的receiver模式
查看>>