uva 11623 - Tic Tac Toe(game)

来源:互联网 发布:java 异常处理机制5种 编辑:程序博客网 时间:2024/06/05 19:38

Problem A: Tic Tac Toe

The game of Tic Tac Toe is played on ann-by-n grid (wheren is usually but not necessarily three). Two players alternate placing symbols on squares of the grid. One player places Xes and the other player places Os. The player placing Xes always goes first. When the grid contains a vertical, horizontal, or diagonal sequence of at leastm consecutive squares all containing the same symbol, the game ends and the winner is the player who placed the last symbol. When all the squares of the grid are filled, if neither player has won, the game ends in a draw.

Your task is to analyze the state of a Tic Tac Toe board, and determine whether the game is still in progress, or if it has completed, who won, or if the game ended in a draw. You should also detect erroneous states of the Tic Tac Toe board that could never occur during an actual game.

Input Specification

The first line of input contains a single integer, the number of test cases to follow. The first line of each test case contains the two integersn andm, separated by spaces, with 1 <=m <= n <= 1000. The followingn lines of the test case each contain one row of the Tic Tac Toe board. Each of these lines contains exactlyn characters, and each of these characters is either anX, an O, or a period (.), indicating an empty square.

Sample Input

13 3..XOOX..X

Output Specification

For each test case, output a single line containing the appropriate string X WINS,O WINS, orDRAW if the game is over, the stringIN PROGRESS if the game has not yet finished, orERROR if the state of the board could never occur during a game.

Output for Sample Input

X WINS
这题关键是ERROR的情况,我总结如下:1、'X'出现的比'O'少,则输出ERROR;2、'X'出现次数和'O'出现次数相差超过1,则输出ERROR;3、'X'和'O'都赢了,,则输出ERROR;4、'X'赢的时候,'X'出现的次数和'O'出现次数相差不是1,则输出ERROR;(因为'X'是先手)5、赢者连续的长度必须 < 2*m,否则输出ERROR;(因为>=2*m的话,说明之前就已经赢了,然后结束了)6、若赢者有多个长度满足要求必定交于一点,而且交点两边的长度一定要 < m,否则输出ERROR;以上条件最难判断的是最后一个,我首先用dfs得到交点,然后在做判断。下面具体说明:1、sum[maxn][maxn][5];//用数组记录当前格子的位置和4个方向的最长长度:
这样每个连续的最长长度就可以求出来了!//0 行 1 列 2 左斜 3 右斜2、struct position{    int x , y , dir;    position(int a = 0 , int b = 0 , int c = 0){        x = a , y = b , dir = c;    }};//用结构体记录连续长度超过m是的点和它的方向;比如:6 3X.....X....OXXO...X.XOO.X........OO.我就记录了(2,0)(3,0)(4,0)(3,2)这4个点和来自的方向,3、vis[maxn][maxn]数组在调用dfs()找交点的时候用,初始为0,记录的是当前这个格子有多少条路经过,每次从2中的记录的点为入口往前递归,最后如果发现有一个点经过路径的条数==2中记录的点的个数,那么这个点就是交点,如果没有发现这个点,说明当前这个图是ERROR。这个点记为(centerX , centerY)。如果有路径在这个点的前半段或后半段(不包括交点) >= m那么这个图是错误的。如果是前半段>=m,用刚才的dfs()找交点是找不到的,所以很巧妙地避开了前半段的情况,不信在纸上画画写写就知道为什么了!现在只要考虑后半段。后半段只要有2中的点到交点的长度(不包括交点)>=m,那么就是错误的,这个很好判断吧~
特别注意:
1 1
X
X WINS完毕!
#include <iostream>#include <cstdio>#include <string>#include <map>#include <vector>#include <cmath>using namespace std;struct position{    int x , y , dir;    position(int a = 0 , int b = 0 , int c = 0){        x = a , y = b , dir = c;    }};vector<position> X_p , O_p;const int maxn = 1010;const int dr[4] = {0 , 1 , 1 , 1};const int dl[4] = {1 , 0 , -1 ,1};string mp[maxn];map<char , int> total;int X_sum , O_sum , sum[maxn][maxn][5] , n , m , vis[maxn][maxn] , centerX , centerY;bool ERROR;//0 行 1 列 2 左斜 3 右斜void initial(){    for(int i = 0; i < maxn; i++){        for(int j = 0; j < maxn; j++){            for(int k = 0; k < 5; k++){                sum[i][j][k] = 0;            }            vis[i][j] = 0;        }        mp[i].clear();    }    X_sum = 0;    O_sum = 0;    total['X'] = 0;    total['O'] = 0;    ERROR = false;    centerX = 0;    centerY = 0;    X_p.clear();    O_p.clear();}void readcase(){    scanf("%d%d" , &n, &m);    for(int i = 0; i < n; i++){        cin >> mp[i];    }}void computing(){    for(int i = 0; i < n; i++){        for(int j = 0; j < n; j++){            if(mp[i][j] == 'X'){                total['X']++;                for(int k = 0; k < 4; k++){                    sum[i][j][k]++;                    if(m <= sum[i][j][k]){                        X_sum = 1;                        X_p.push_back(position(i , j , k));                    }                    if(sum[i][j][k] >= 2*m){                        ERROR = true;                        return;                    }                    int r = i+dr[k] , c = j+dl[k];                    if(r >= 0 && r < n && c >= 0 && c < n && mp[r][c] == 'X'){                        sum[r][c][k] = max(sum[r][c][k] , sum[i][j][k]);                    }                }            }            if(mp[i][j] == 'O'){                total['O']++;                for(int k = 0; k < 4; k++){                    sum[i][j][k]++;                    if(m <= sum[i][j][k]){                        O_sum = 1;                        O_p.push_back(position(i , j , k));                    }                    if(sum[i][j][k] >= 2*m){                        ERROR = true;                        return;                    }                    int r = i+dr[k] , c = j+dl[k];                    if(r >= 0 && r < n && c >= 0 && c < n && mp[r][c] == 'O'){                        sum[r][c][k] = max(sum[r][c][k] , sum[i][j][k]);                    }                }            }        }    }}bool dfs(int i , int j , int k , int psize , char player){    vis[i][j]++;    if(vis[i][j] == psize){        centerX = i;        centerY = j;        return true;    }    int r = i-dr[k] , c = j-dl[k];    if(r >= 0 && r < n && c >= 0 && c < n && mp[r][c] == player){        if(dfs(r , c , k , psize , player)) return true;    }    return false;}void out(){    if(ERROR || total['X'] < total['O']){        printf("ERROR\n");        return;    }    if(total['X']+total['O'] == n*n){        if(total['X'] == total['O'] || total['X']-total['O'] == 1){if(n == 1) printf("X WINS\n");else printf("DRAW\n");        }        else printf("ERROR\n");        return;    }    if(total['X']-total['O'] < -1 || total['X']-total['O'] > 1){        printf("ERROR\n");        return;    }    if(X_sum && O_sum){        printf("ERROR\n");        return;    }    if(X_sum){        if(total['X'] - total['O'] != 1){            printf("ERROR\n");            return;        }        for(int i = 0; i < X_p.size(); i++){            if(dfs(X_p[i].x , X_p[i].y , X_p[i].dir , X_p.size() , 'X')){                for(int j = 0; j < X_p.size(); j++){                    if(abs(X_p[j].x-centerX)+1 > m || abs(X_p[j].y-centerY)+1 > m){                                                printf("ERROR\n");                        return;                    }                }                printf("X WINS\n");                return;            }        }        printf("ERROR\n");        return;    }    if(O_sum){        if(total['X'] != total['O']){            printf("ERROR\n");            return;        }        for(int i = 0; i < O_p.size(); i++){            if(dfs(O_p[i].x , O_p[i].y , O_p[i].dir , O_p.size() , 'O')){                for(int j = 0; j < O_p.size(); j++){                    if(abs(O_p[j].x-centerX)+1 > m || abs(O_p[j].y-centerY)+1 > m){                        printf("ERROR\n");                        return;                    }                }                printf("O WINS\n");                return;            }        }        printf("ERROR\n");        return;    }    printf("IN PROGRESS\n");}int main(){    int t;    scanf("%d" , &t);    while(t--){        initial();        readcase();        computing();        out();    }    return 0;}


0 0
原创粉丝点击