zoukankan      html  css  js  c++  java
  • Treblecross

    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 first 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 first player can get three ‘X’ in a row. If, on the other hand, the first 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 first 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, first 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

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=210;
    int t,res[maxn],way,len,sg[maxn];
    char str[maxn];
    bool judge(){
       for(int i=0;i<len-2;i++)
       if(str[i]=='X'&&str[i+1]=='X'&&str[i+2]=='X')return true;//if have win(three_X_inline),just true
       return false;//or just return false
    }
    int getsg(int x){
        if(sg[x]!=-1)return sg[x];//if has work the sg out,just return 
        if(x==0) return sg[x]=0;//if it's the first one ,just return it's sg as 0
        bool vis[maxn];int t;memset(vis,false,sizeof(vis));//set a visit array and initialization it
        for(int i=1;i<=x;i++){
           int t=getsg(max(0,i-3))^getsg(max(0,x-i-2));
           vis[t]=true;//get the next_sg and set it has been visited
        }
        for(int i=0;;i++){if(vis[i])continue;return sg[x]=i;}//if it has vist just go on ,or just return it and set the sg_mark as it
    }
    int getres(){
        for(int i=0;i<len;i++)
           if(str[i]=='.'){//if it is a space
                str[i]='X';//just work there(put X there)
                if (judge()){str[i]='.';return false;}//if can win,just set it back to the space and return false
                str[i]='.';//set it back
            }int ans=0,num=0;//set two variable
        for(int i=0;i<len;i++)
            if(str[i]=='X'||(i>=1&&str[i-1]=='X')||(i>=2&&str[i-2]=='X')||(i+1<len&&str[i+1]=='X')||(i+2<len&&str[i+2]=='X'))
            //if this point is X |or|left one is X|or|the last second point is X|or|right one is X|or|the next second point is X
                ans^=getsg(num),num=0;//renew the mark,and initialization the num
            else num++;//or just renew the num
        ans^=getsg(num);return ans==0;//renew the final mark 
        //if the mark is false ,just return true or just return false
    }
    void solve(){way=0;len=strlen(str);//initialization the mark and the lenth of the map
        for(int i=0;i<len;i++)//deal with every map_part
        {
            if(str[i]!='.')continue;//if it is not a space ,just run to next map_part
            str[i]='X';//if it is a space just work there(put X there)
            if (judge()||getres())//if can win or the mark is false just set it into the win_case and set the place back
            res[++way]=i+1;str[i]='.';
        } 
    }
    int main(){memset(sg,-1,sizeof(sg));scanf("%d",&t);//initialization sg and read the case_num
        while(t--){
            scanf("%s",str);solve();//read the map,and initialization_operation
            if(way==0)puts("LOSING
    ");//if the win_case_num is 0,just has no win_solution ,just the lose_case
            else{
                puts("WINNING");//or ,the win_case
                for(int i=1;i<=way;i++)printf("%d%c",res[i],i==way?'
    ':' ');//printf every win_method. if i==way printf
     or printf' '
            }
        }return 0;
    }

    program is just above ,the program is the best solution

  • 相关阅读:
    Shell中调用、引用、包含另一个脚本文件的三种方法
    mysql基础
    传智博客(JavaWeb方面的所有知识)听课记录(经典)
    nginx配置负载均衡与反向代理
    nginx 详解
    iOS开发之集成ijkplayer视频直播
    Nginx配置文件nginx.conf中文详解(总结)
    WorldWind源码剖析系列:数学引擎类MathEngine
    WorldWind源码剖析系列:二维点类Point2d和三维点类Point3d
    WorldWind源码剖析系列:枚举类型
  • 原文地址:https://www.cnblogs.com/muzu/p/7154615.html
Copyright © 2011-2022 走看看