• 【UVA10561】Treblecross(SG函数)


    题意:有n个格子排成一行,其中一些格子里面有字符X。两个游戏者轮流操作,每次可以选一个空格,在里面放上字符X。

    如果此时有3个连续的X出现,则该游戏者赢得比赛。初始条件下不会有3个X连续出现。

    判断先手胜负情况,若必胜则升序输出先手第一步的所有可选必胜策略

    n<=200

    思路:如果有XX或者X.X出现则一定先手胜

    一个结论:X的旁边和旁边的旁边不能放X

    于是整个游戏被不能放X的区域分成了若干个独立的片段,每次都可以选择一个片段进行游戏,就是若干个游戏的和

    由于每个棋盘片段都是连续的,想到用一个正整数(即长度)来表示状态,g(x)表示由连续的x个格子组成的棋盘所对应的SG函数值

    则有递推方程g(x)=mex(g(x-3),g(x-4),g(x-5),g(1)^g(x-6),g(2)^(x-7)……)

    有了g函数,很容易算出初始局面的SG函数,所有使得后继专题SG值为0的决策即为所求

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cmath>
      6 typedef long long ll;
      7 using namespace std;
      8 #define N   21000
      9 #define oo  10000000
     10 #define MOD 1000000007
     11 
     12 int g[N],flag[N],b[N],c[N],d[N],n;
     13 char a[N];
     14 
     15 int isok(int x)
     16 {
     17     int k=0;
     18     a[x]='X';
     19     for(int i=2;i<=n-1;i++)
     20     {
     21         if(a[i]=='X'&&a[i+1]=='X'&&a[i-1]=='.'){k=i-1; break;}
     22         if(a[i]=='X'&&a[i-1]=='X'&&a[i+1]=='.'){k=i+1; break;}
     23         if(a[i]=='.'&&a[i-1]=='X'&&a[i+1]=='X'){k=i; break;}
     24     }
     25     if(k)
     26     {
     27         a[x]='.'; 
     28         return 0;
     29     }
     30     for(int i=1;i<=n;i++) b[i]=0;
     31     for(int i=1;i<=n;i++)
     32      if(a[i]=='X') 
     33       for(int j=-2;j<=2;j++)
     34        if(i+j>0&&i+j<=n) b[i+j]=1;
     35     int ans=0;
     36     int s=0;
     37     for(int i=1;i<=n;i++)
     38      if(b[i]==0) s++;
     39       else if(s) 
     40       {
     41          ans^=g[s]; 
     42         s=0;
     43       }
     44      if(s) ans^=g[s]; 
     45      a[x]='.';
     46      if(ans) return 0;
     47      return 1;
     48 }
     49 
     50 int main()
     51 { 
     52     //freopen("uva10561.in","r",stdin);
     53     //freopen("uva10561.out","w",stdout); 
     54     g[0]=0;
     55     g[1]=g[2]=g[3]=1;
     56     g[4]=g[5]=2; 
     57     for(int i=6;i<=200;i++)
     58     {
     59         memset(flag,0,sizeof(flag));
     60         for(int j=3;j<=5;j++) flag[g[i-j]]=1;
     61         for(int j=6;j<=i;j++)
     62          if(i-j>=0) flag[g[j-5]^g[i-j]]=1;
     63         int j=0;
     64         while(flag[j]) j++;
     65         g[i]=j; 
     66     }
     67     //for(int i=1;i<=200;i++) printf("%d %d
    ",i,g[i]);
     68     int cas;
     69     scanf("%d",&cas);
     70     while(cas--)
     71     {
     72         scanf("%s",a+1);
     73         n=strlen(a+1);
     74         for(int i=1;i<=n;i++) d[i]=0;
     75         for(int i=2;i<=n-1;i++)
     76         {
     77              if(a[i]=='X'&&a[i+1]=='X'&&a[i-1]=='.') d[i-1]=1; 
     78              if(a[i]=='X'&&a[i-1]=='X'&&a[i+1]=='.') d[i+1]=1; 
     79              if(a[i]=='.'&&a[i-1]=='X'&&a[i+1]=='X') d[i]=1;
     80         }
     81         for(int i=1;i<=n;i++) b[i]=0;
     82         for(int i=1;i<=n;i++)
     83          if(a[i]=='X') 
     84           for(int j=-2;j<=2;j++)
     85            if(i+j>0&&i+j<=n) b[i+j]=1;
     86         int ans=0;
     87         int s=0;
     88         for(int i=1;i<=n;i++)
     89          if(b[i]==0) s++;
     90           else if(s) 
     91           {
     92               ans^=g[s];
     93               s=0;
     94           }
     95         if(s) ans^=g[s];
     96         s=0;
     97         for(int i=1;i<=n;i++) s+=d[i];
     98         if(ans||s) 
     99         {
    100             printf("WINNING
    ");
    101             int m=0;
    102             for(int i=1;i<=n;i++)
    103              if(a[i]=='.'&&isok(i)) d[i]=1;
    104             for(int i=1;i<=n;i++)
    105              if(d[i]) c[++m]=i;
    106             for(int i=1;i<=m-1;i++) printf("%d ",c[i]);
    107             printf("%d
    ",c[m]);
    108         }
    109          else 
    110          {
    111              printf("LOSING
    ");
    112              printf("
    ");
    113          }
    114     }
    115     return 0;
    116 }
    117     
  • 相关阅读:
    夺命雷公狗---ECSHOP---08---商品页的拇改成星星
    夺命雷公狗---ECSHOP---07---商品价格的遍历
    夺命雷公狗---ECSHOP---06---商品倒计时的实现
    WordPress博客密码忘记的解决方法
    夺命雷公狗---js_mv思路
    LAMP前一定要关闭防火墙
    夺命雷公狗---Smarty NO:25 缓存控制技术2(完结)
    夺命雷公狗---Smarty NO:24 缓存控制技术1
    夺命雷公狗---Smarty NO:23 常用方法
    夺命雷公狗---Smarty NO:22 常量—变量
  • 原文地址:https://www.cnblogs.com/myx12345/p/9953341.html
Copyright © 2020-2023  润新知