zoukankan      html  css  js  c++  java
  • POJ 2311 Cutting Game(SG函数)

    题目描述

    意思就是说两个人轮流剪纸片,直到有一个人剪出1*1的方格就算这个人赢了。然后给出纸片的长和宽,求先手会赢还是会输

    (1<=n,m<=200)

    题解

    看了一眼,这不是裸的SG吗

    啪啪啪写完,一交T了,居然没算复杂度就交了。。。

    首先明确,把纸片分成两部分之后的SG是分成两个纸片的异或。

    一个非常自然的想法就是,枚举如何分割这个纸片,然后求mex。

    但是这样显然会T。(200^4)

    其实作为一个正常人,1*x这样的纸片是不会切出来的,这显然是一个必败局面。

    然后2*2,2*3,3*2这样的局面也是必败的,搜到这样的局面就可以退出了。

    最后,比如一个5*5的纸片,切成3*5+2*5和切成2*5+3*5是一样的。

    所以一个x*y的纸片枚举的时候从2枚举到x/2就行。

    这样就能AC了

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 const int N=210;
     8 int sg[N][N],a[N*2],n,m;
     9 int get_sg(int x,int y){
    10     if(sg[x][y]!=-1)return sg[x][y];
    11     bool a[250];
    12     memset(a,0,sizeof(a));
    13     for(int i=2;i<=x-i;i++)a[get_sg(i,y)^get_sg(x-i,y)]=1;
    14     for(int i=2;i<=y-i;i++)a[get_sg(x,i)^get_sg(x,y-i)]=1;
    15     for(int i=0;;i++){
    16         if(a[i]==0)return sg[x][y]=i;
    17     }
    18 }
    19 int main(){
    20     memset(sg,-1,sizeof(sg));
    21     sg[2][2]=sg[3][2]=sg[2][3]=0;
    22     while(scanf("%d%d",&n,&m)!=EOF){
    23         if(get_sg(n,m)==0)printf("LOSE
    ");
    24         else printf("WIN
    ");
    25     }
    26     return 0;
    27 }
  • 相关阅读:
    session 和 aplication 相关总结
    asp.net网站发布时碰到的一些问题
    考前防脑瘫防挂分预防针
    【游记】NOIP2021 白给记
    SELECT list is not in GROUP BY clause and contains nonaggregated
    StringUtils.isEmpty()
    gitLab生成SSH私钥后上传代码及获取代码
    tomcat配置https请求访问
    Mybatis:映射文件概述 & 增删改查
    Mybatis:核心文件概述
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9742866.html
Copyright © 2011-2022 走看看