zoukankan      html  css  js  c++  java
  • LightOJ 1229 Tablecross

    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 are empty. In each turn a player puts an X in an empty cell, and if the move results three X next to each other, that player wins.

    Given the current state of the game, you are to determine if the current player to move can win the game assuming both players play optimally.

    Consider the game where the board size is 5 cells. If the first player puts an 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 players move 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

    Input starts with an integer T (≤ 200), denoting the number of test cases.

    Each case starts with a line containing a string denoting the current status of the game. 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, print the case number and the positions on the board, where the player to move may put an X and win the game. The positions should be separated by a single space, and be in increasing order. The leftmost position on the board is 1. If there is no such position print 0.

    Sample Input

    4

    .....

    X.....X..X.......X....X..X

    .X.X...X

    ..................

    Sample Output

    Case 1: 3

    Case 2: 0

    Case 3: 3

    Case 4: 5 6 13 14

    题解:题目意思就是给你一行字符串由 '.'和'X'组成,然后两个人交替将一个‘.’

    变成'X'.如果某个人先形成连续的3个‘X’,则这个人就取得胜利。问先手必胜的位置是否存在,

    如果存在,有多少个,并依次输出其位置;这题肯定是枚举每一个位置,判断是否可以胜利,

    对于SG[x]表示长度为x的‘.’区间的SG值,然后对于每一个位置(不是'X'的位置),判断其由

    ‘.’变成'X'之后是否可以形成连续3个'X'的必胜状态,是否会形成.XX或XX.或X.X的必败状态;如果都不是

    再去枚举每一个区间的SG值,再将其异或ans,就得到这一个位置的SG值,为0必胜,不为零必败;

    参考代码:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<vector>
     5 using namespace std;
     6 typedef long long ll;
     7 #define clr(a,val) memset(a,val,sizeof(a))
     8 const int maxn=210;
     9 int T,SG[maxn],len;
    10 vector<int> v;
    11 char s[maxn],s1[maxn];
    12 int getSG(int m)
    13 {
    14     if(m<0) return 0;
    15     if(SG[m]!=-1) return SG[m];
    16     bool vis[maxn];clr(vis,0);
    17     for(int i=1;i<=m;++i) vis[getSG(i-3)^getSG(m-i-2)]=1;
    18     int t=0;
    19     while(vis[t]) ++t;
    20     return SG[m]=t; 
    21 }
    22 
    23 bool check(int x)
    24 {
    25     strcpy(s1,s);
    26     if(s1[x]=='X') return 0;
    27     s1[x]='X';
    28     for(int i=0;i<len-2;++i) {if(s1[i]=='X'&&s1[i+1]=='X'&&s1[i+2]=='X') return 1;}
    29     for(int i=0;i<len-1;++i) {if(s1[i]=='X'&&s1[i+1]=='X') return 0;}
    30     for(int i=0;i<len-2;++i) {if(s1[i]=='X'&&s1[i+2]=='X') return 0;}
    31     int j=-1,f=0,ans=0;
    32     for(int i=0;i<len;++i)
    33     {
    34         if(s1[i]=='X')
    35         {
    36             if(f) ans^=getSG(i-j-5);
    37             else ans^=getSG(i-j-3),f=1;    
    38             j=i;
    39         }
    40     }
    41     ans^=getSG(len-j-3);
    42     return ans==0;
    43 }
    44 
    45 int main()
    46 {
    47     scanf("%d",&T);
    48     memset(SG,-1,sizeof SG);
    49     for(int cas=1;cas<=T;++cas)
    50     {
    51         scanf("%s",s);
    52         v.clear(); 
    53         len=strlen(s);
    54         for(int i=0;i<len;++i)
    55         {
    56             if(check(i)) v.push_back(i+1);
    57         }    
    58         printf("Case %d:",cas);
    59         if(v.size())
    60         {
    61             for(int i=0;i<v.size();++i) printf(" %d",v[i]);
    62             puts("");
    63         }
    64         else printf(" 0
    ");
    65     }    
    66     
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    特征词选择算法对文本分类准确率的影响(前言)
    答火星人.NET。如何使用我的本科毕业程序 正文提取DEMO
    有关matlab画图格式的部分代码
    文本分类中的特征词选择算法系列科普(前言AND 一)
    c++杂项备忘
    写一点应用关于 Lucene.Net,snowball的重新组装(一)在Lucene.Net中加入词性标注与词根还原功能
    C++字符串处理:批量去重,以及大写变小写
    Python打印到文件
    中文分词:采用二元词图以及viterbi算法(三)
    博客园和百度空间,我的两个家
  • 原文地址:https://www.cnblogs.com/csushl/p/10390177.html
Copyright © 2011-2022 走看看