• 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 }
  • 相关阅读:
    laravel读excel
    React 还是 Vue: 你应该选择哪一个Web前端框架?
    React16版本的新特性
    你真的了解React吗
    express操作数据库
    跨域的九种解决方式
    Koa基本使用
    luogu3806 【模板】点分治1
    luogu2634 聪聪可可
    poj1741 Tree
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9742866.html
Copyright © 2020-2023  润新知