• uva10561


    Treblecross is a two player game where the goal is to get three `X' in a row on a one-dimensional board.
    At the start of the game all cells in the board is empty. In each turn a player puts a `X' in an empty
    cell, and if that results in there being three `X' next to each other, that player wins.
    Given the current state of the game, you are to determine if the player to move can win the game
    assuming both players play perfectly. If so, you should also print all moves that will eventually lead to
    a win.
    Consider the game where the board size is 5 cells. If the rst player puts a `X' at position three (in
    the middle) so the state becomes `..X..', he will win the game as no matter where the other player
    puts his `X', the rst player can get three `X' in a row. If, on the other hand, the rst player puts the
    `X' in any other position, the second player will win the game by putting the `X' in the opposite corner
    (for instance, after the second player moves the state might be `.X..X'). This will force the rst player
    to put an `X' in a position so the second player wins in the next move.
    Input
    The input begins with an integer N (N < 100), the number of states that will follow. Each state is
    represented by a string on a line by itself. The string will only contain the characters `.' and `X'. The
    length of the string (the size of the board) will be between 3 and 200 characters, inclusive. No state
    will contain three `X' in a row.
    Output
    For each case, rst output `WINNING' or `LOSING' depending on if the player to move will win or lose the
    game. On the next line, output in increasing order all positions on the board where the player to move
    may put an X and win the game. The positions should be separated by a blank, and be in increasing
    order. The leftmost position on the board is 1.
    Sample Input
    4
    .....
    X.....X..X.............X....X..X
    .X.X...X
    ...............................................
    Sample Output
    WINNING
    3
    LOSING
    WINNING
    3
    WINNING
    1 12 15 17 20 24 28 31 33 36 47

    白书上的原题,注意此题细节非常多。

    code:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #define maxn 205
     7 using namespace std;
     8 char ch,s[maxn];
     9 int ti,n,sg[maxn],cnt,l,idx,tmp;
    10 bool ok,bo[maxn*maxn],exist[maxn],flag,first;
    11 struct DATA{
    12     int l,r,siz;
    13 }list[maxn];
    14 void read(int &x){
    15     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
    16     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    17     if (ok) x=-x;
    18 }
    19 void calc(int k){
    20     for (int i=1,t1,t2;i<=k;i++){
    21         t1=(i-2)-1,t2=k-(i+2);
    22         if (t1>0&&sg[t1]==-1) calc(t1);
    23         if (t2>0&&sg[t2]==-1) calc(t2);
    24     }
    25     memset(bo,0,sizeof(bo));
    26     for (int i=1,t1,t2,t;i<=k;i++){
    27         t=0,t1=(i-2)-1,t2=k-(i+2);
    28         if (t1>0) t^=sg[t1];
    29         if (t2>0) t^=sg[t2];
    30         bo[t]=1;
    31     }
    32     for (int i=0;;i++) if (!bo[i]){sg[k]=i;break;}
    33 }
    34 void prepare(){
    35     memset(sg,-1,sizeof(sg));
    36     for (int i=200;i>=1;i--) if (sg[i]==-1) calc(i);
    37 }
    38 void write(int x){
    39     if (first) first=0;
    40     else putchar(' ');
    41     printf("%d",x);    
    42 }
    43 int main(){
    44     prepare();
    45     for (read(ti);ti;ti--){
    46         memset(s,0,sizeof(s));
    47         scanf("%s",s+1);
    48         n=strlen(s+1),flag=0,idx=cnt=tmp=0,l=(s[1]=='X'?0:1);
    49         memset(list,0,sizeof(list));
    50         for (int i=1;i<=n;i++)
    51             if (s[i]=='X'){
    52                 if (s[i+1]=='X'||s[i+2]=='X'){flag=1;break;}
    53                 if ((i-2)-l>0) list[++idx]=(DATA){l,i-3,i-2-l};
    54                 l=i+3;
    55             }
    56         if (l<=n) list[++idx]=(DATA){l,n,n-l+1};
    57         if (flag){
    58             puts("WINNING");
    59             memset(exist,0,sizeof(exist)); first=1;
    60             for (int i=1;i<=n;i++)
    61                 if (s[i]=='X'){
    62                     if (s[i+1]=='X'){
    63                         if (i-1>=1&&!exist[i-1]) write(i-1),exist[i-1]=1;
    64                         if (i+2<=n&&!exist[i+2]) write(i+2),exist[i+2]=1;
    65                     }
    66                     if (s[i+2]=='X'){
    67                         if (i+1<=n&&!exist[i+1]) write(i+1),exist[i+1]=1;
    68                     }
    69                 }
    70             puts("");
    71             continue;
    72         }
    73         for (int i=1;i<=idx;i++) tmp^=sg[list[i].siz];
    74         if (tmp){
    75             puts("WINNING");
    76             first=1;
    77             for (int i=1,t;i<=idx;i++){
    78                 t=sg[list[i].siz];
    79                 for (int j=list[i].l,t1,t2,t3;j<=list[i].r;j++){
    80                     t1=(j-2)-list[i].l,t2=list[i].r-(j+2),t3=0;
    81                     if (t1) t3^=sg[t1];
    82                     if (t2) t3^=sg[t2];
    83                     if (!(tmp^t^t3)) write(j); 
    84                 }
    85             }
    86             puts("");
    87             continue;
    88         }
    89         else puts("LOSING"),puts("");
    90     }
    91     return 0;
    92 }
  • 相关阅读:
    Subversion学习笔记
    单元测试 学习笔记 之五
    单元测试 学习笔记 之四
    将全球通讯簿导入pop3客户端联系人
    isa 2006 sp1发布
    使用POWERSHELL管理OCS 2007
    SCCM 2007 排错
    空空排错日志:OCS错误日志14501等解决办法
    在AD没有备份的情况下还原被删除的数据
    冲击波又回来啦?
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/4712746.html
Copyright © 2020-2023  润新知