博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ1434:[ZJOI2009]染色游戏(博弈论)
阅读量:6945 次
发布时间:2019-06-27

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

Description

一共n×m个硬币,摆成n×m的长方形。dongdong和xixi玩一个游戏,每次可以选择一个连通块,并把其中的硬币全部翻转,但是需要满足存在一个硬币属于这个连通块并且所有其他硬币都在它的左上方(可以正左方也可以正上方),并且这个硬币是从反面向上翻成正面向上。dongdong和xixi轮流操作。如果某一方无法操作,那么他(她)就输了。dongdong先进行第一步操作,假设双方都采用最优策略。问dongdong是否有必胜策略。

Input

第一行一个数T,表示他们一共玩T局游戏。
接下来是T组游戏描述。每组游戏第一行两个数n;m,
接下来n行每行m个字符,第i行第j个字符如果是“H”表示第i行第j列的硬币是正面向上,
否则是反面向上。第i行j列的左上方是指行不超过i并且列不超过j的区域。
1≤n;m≤100,1≤T≤50。

Output

对于每局游戏,输出一行。
如果dongdong 存在必胜策略则输出“- -”(不含 引号) 否则输出“= =”(不含引号)。
(注意输出的都是半角符号,即三个符号 ASCII 码分别为45,61,95)

Sample Input

32
3
HHH
HHH
2 3
HHH
TTH
2 1
T
H

Sample Output

= =
- -
- -

Solution

有一个叫$yyb$的神仙她说这个题打表就可以了,于是我就抄了个爽。

首先要知道翻硬币游戏的一个结论。

假设你操作的最右(下)方的硬币必须是正着的,那么局面的$SG$值为局面中每个正面朝上的棋子单一存在时的$SG$值的异或和。

单一存在时$SG$的异或和就可以打表搞了。规律是:(左上角为$(0,0)$)

如果$i=0$且$j=0$,$SG(i,j)=2^{i+j}$。

否则$SG(i,j)=lowbit(i+j+1)$。

可以发现虽然这个$SG$值太大,可他二进制下都只有一位啊,开个$vis$数组记一下就好了。

Code

1 #include
2 #include
3 #include
4 #include
5 #define N (509) 6 using namespace std; 7 8 int T,n,m,flag,vis[N]; 9 char s[N];10 11 int lowbit(int x) {
return x&(-x);}12 13 int SG(int i,int j)14 {15 if (i && j) return i+j;16 return log2(lowbit(i+j+1));17 }18 19 int main()20 {21 scanf("%d",&T);22 while (T--)23 {24 flag=0;25 memset(vis,0,sizeof(vis));26 scanf("%d%d",&n,&m);27 for (int i=0; i

转载于:https://www.cnblogs.com/refun/p/10108420.html

你可能感兴趣的文章
MAC下安装与配置MySQL
查看>>
linux系统的crond服务
查看>>
Restore Volume 操作 - 每天5分钟玩转 OpenStack(60)
查看>>
sqool导出oracle数据
查看>>
MyBatis动态传入表名,字段名参数的解决办法
查看>>
Windows平台下安装Hadoop
查看>>
oracle11gR2静默安装
查看>>
理解javascript中的浏览器窗口——窗口基本操作
查看>>
Directx11学习笔记【二十】 使用DirectX Tool Kit加载mesh
查看>>
【Linux】NAT模式下关于主机ping不通虚拟机的问题
查看>>
SpringMVC 参数注入
查看>>
mysql去重, 把url重复且区为空的中去掉、统计重复数据、、结果集去重合并成一行...
查看>>
atitit.attilax的软件 架构 理念.docx
查看>>
EF实体框架之CodeFirst四
查看>>
[Tex学习]WinEdit 常用软件快捷键
查看>>
二维码在短信业务应用的初步构思
查看>>
分布式服务器集群架构方案思考
查看>>
Graphviz使用简介(中文乱码的问题)
查看>>
Log4J使用
查看>>
【反编译系列】三、反编译神器(jadx)
查看>>