zoukankan      html  css  js  c++  java
  • [ZJOI2009]染色游戏

    https://www.zybuluo.com/ysner/note/1232377

    题面

    一个(n*m)的长方形上,每个格子上有一硬币。每次需选一联通块并全部翻面,前提是其右下角硬币必须初始为反面。双方轮流行动,问先手是否有必胜策略。

    • (n,mleq50)

    解析

    这是一个二维翻硬币问题。

    先从一维说起。
    一维翻硬币问题有个结论:局面的SG值等于局面中所有反面朝上的硬币单独存在时的SG值的异或和

    于是试着算一下:(其实我就是想试试怎么算(SG)值)
    (x)表示第(x)个硬币单独反面向上的情况。
    据((mex)表示取括号内不包含的 最小非负整数)$$SG(x)=mex_{0leq i<x}(igotimes_{j=1}^iSG(j))$$
    (SG(0)=0)

    (SG(1)=1),因操作后状态((1,0,0,0))可转移到状态((0,0,0,0));

    (SG(2)=2),因操作后状态((0,1,0,0))可转移到状态((0,0,0,0))和状态((1,0,0,0))

    (mex(0,SG(1))=1);

    (SG(3)=1),因操作后状态((0,0,1,0))可转移到状态((0,0,0,0))、状态((0,1,0,0))和状态((1,1,0,0))这个状态可由(x=1)状态异或(x=2)状态产生),

    (mex(0,SG(1),SG(1)igotimes SG(2))=2);

    (SG(4)=4),因操作后状态((0,0,0,1))可转移到状态((0,0,0,0))、状态((0,0,1,0))和状态((0,1,1,0))((1,1,1,0))

    (mex(0,SG(1),SG(1)igotimes SG(2),SG(1)igotimes SG(2)igotimes SG(3))=4);

    同理,(SG(5)=4)
    发现规律,(SG(x)=lowbit(x))(相当于只保留最高位)。

    同理,可以试着算二维状态的(SG)值,方法与上类似,懒得打过程了。(矩阵转动后(SG)值不变

    于是得到规律:
    (i==1||j==1)时,(SG(i,j)=lowbit(i+j-1);)
    除此之外,(SG(i,j)=2^{i+j-2})

    (long long)随便用(bool)存下各位是否为(1)就好了。

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    #define re register
    #define il inline
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int N=205,mod=2017;
    int n,m,mp[2000],ans;
    bool vis[N];
    il ll gi()
    {
      re ll x=0,t=1;
      re char ch=getchar();
      while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
      if(ch=='-') t=-1,ch=getchar();
      while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
      return x*t;
    }
    il int SG(re int x,re int y)
    {
      if(x==1||y==1) return mp[(x+y-1)&(-x-y+1)];
      else return x+y-2;
    }
    int main()
    {
      ios::sync_with_stdio(false);
      re int T;cin>>T;
      fp(i,1,10) mp[1<<i]=i;
      while(T--)
        {
          memset(vis,0,sizeof(vis));
          cin>>n>>m;
          fp(i,1,n) fp(j,1,m)
        {
          re char c;cin>>c;
          if(c=='T') vis[SG(i,j)]^=1;
        }
          re int tag=0;
          fq(i,n+m-1,0) if(vis[i]) {tag=1;break;}
          puts(tag?"-_-":"=_=");
        }
      
      return 0;
    }
    
  • 相关阅读:
    sqlalchemy presto 时间比较
    python 读取consul配置
    移动平台自动化测试:appium(二)
    移动平台自动化测试:appium(一)
    web自动化测试:watir+minitest(五)
    web自动化测试:watir+minitest(四)
    从智能垃圾桶模型引发的思考?
    AD技巧之敷铜
    AD技巧之如何修改过孔的默认尺寸
    硬件工程师之路之电阻知识
  • 原文地址:https://www.cnblogs.com/yanshannan/p/9392773.html
Copyright © 2011-2022 走看看