zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    [JSOI2008]最小生成树计数
    [SCOI2009]windy数
    Sql Server 存储过程
    Sql Server 表操作
    .NET WebService中使用 Session
    从头入手jenkins
    swiftlint 你所要知道的所有!!
    swiftlint swift代码规范检查神器
    使用RxSwift 实现登录页面的条件绑定
    iOS 设置不同环境下的配置 Debug Release 生产 测试 等等
  • 原文地址:https://www.cnblogs.com/wfj2048/p/8011510.html
Copyright © 2011-2022 走看看