bzoj1434 [ZJOI2009]染色游戏

Posted wfj_2048

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1434 [ZJOI2009]染色游戏相关的知识,希望对你有一定的参考价值。

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 的区域。

Output

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

Sample Input

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

Sample Output

= =
- -
- -

HINT

对于40% 的数据,满足1 ≤ n;m ≤ 5。
对于100% 的数据,满足1 ≤ n;m ≤ 100,1 ≤ T ≤ 50。

 

正解:$SG$函数。

又是这种硬币问题。。我开始以为每次翻转一个矩形,然后写了个$dp$求$SG$函数并成功爆零。。

然后写一个搜索可以发现,如果$i=1$或$j=1$,$SG[i][j]=lb(max(i,j))$,否则$SG[i][j]=2^{i+j-2}$。

但是太大了,所以我们只记录二进制的每一位是否为$0$就行了。

 

 1 #include <bits/stdc++.h>
 2 #define il inline
 3 #define RG register
 4 #define ll long long
 5 #define lb(x) (x & -x)
 6 
 7 using namespace std;
 8 
 9 int cnt[205],bin[205],n,m,ans;
10 
11 il int gi(){
12   RG int x=0,q=1; RG char ch=getchar();
13   while ((ch<0 || ch>9) && ch!=-) ch=getchar();
14   if (ch==-) q=-1,ch=getchar();
15   while (ch>=0 && ch<=9) x=x*10+ch-48,ch=getchar();
16   return q*x;
17 }
18 
19 il char gc(){
20   RG char ch=getchar();
21   while (ch!=H && ch!=T) ch=getchar(); return ch;
22 }
23 
24 il void get(RG int x,RG int y){
25   if (x==1){ cnt[bin[lb(y)]]^=1; return; }
26   if (y==1){ cnt[bin[lb(x)]]^=1; return; }
27   cnt[x+y-2]^=1; return;
28 }
29 
30 il void work(){
31   n=gi(),m=gi(),memset(cnt,0,sizeof(cnt));
32   for (RG int i=1;i<=n;++i)
33     for (RG int j=1;j<=m;++j)
34       if (gc()==T) get(i,j);
35   for (RG int i=0;i<=200;++i)
36     if (cnt[i]){ puts("-_-"); return; }
37   puts("=_="); return;
38 }
39 
40 int main(){
41 #ifndef ONLINE_JUDGE
42   freopen("color.in","r",stdin);
43   freopen("color.out","w",stdout);
44 #endif
45   for (RG int i=2;i<=100;++i) bin[i]=bin[i>>1]+1;
46   RG int T=gi(); while (T--) work(); return 0;
47 }

 

以上是关于bzoj1434 [ZJOI2009]染色游戏的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1411 ZJOI2009 硬币游戏

bzoj1413: [ZJOI2009]取石子游戏

bzoj1413 [ZJOI2009]取石子游戏

BZOJ 1411&&Vijos 1544 : [ZJOI2009]硬币游戏递推,快速幂

BZOJ 1059 ZJOI2007 矩阵游戏

bzoj 1433: [ZJOI2009]假期的宿舍