哈尔滨理工大学第六届程序设计团队赛G OX(博弈搜索)

来源:互联网 发布:tabletoexcel.js 编辑:程序博客网 时间:2024/05/22 06:43

题意:给出井字棋的当前状态和先手,问最终是谁会赢,或者是平局?


思路:将每一个状态用三进制压缩,设dp[S][now]为当前状态为S,下棋的人是now时的胜负状态,那么当前如果对方连成了3子,己方就输了,或者自己连城了3子,己方就赢了,或者是棋盘已满,则为平局。如果当前状态可以进入至少一个必败态,那么当前状态是必胜态,否则如果可以进入一个平局态,那么当前状态就是平局态,否则是必败态。


#include<cstdio>#include<cstring>#include<algorithm>const int maxn = 1e5 + 10;using namespace std;char s[3];int T, st, dp[maxn][3];int dfs(int S, int now) {    int &ans = dp[S][now];    if(ans != -2) return ans;    int c[3][3], sum = 0;    for(int i = 2; i >= 0; i--) {        for(int j = 2; j >= 0; j--) {            c[i][j] = S % 3;            S /= 3;            if(c[i][j]) sum++;        }    }    int n1 = 0, n2 = 0;    for(int i = 0; i < 3; i++) {        if(c[i][0] == c[i][1] && c[i][1] == c[i][2]) {            if(c[i][0] == 1) n1++;            if(c[i][0] == 2) n2++;        }        if(c[0][i] == c[1][i] && c[1][i] == c[2][i]) {            if(c[0][i] == 1) n1++;            if(c[0][i] == 2) n2++;        }    }    if(c[0][0] == c[1][1] && c[1][1] == c[2][2]) {        if(c[0][0] == 1) n1++;        if(c[0][0] == 2) n2++;    }    if(c[2][0] == c[1][1] && c[1][1] == c[0][2]) {        if(c[1][1] == 1) n1++;        if(c[1][1] == 2) n2++;    }    if(n1 && now == 2) return ans = 0;    if(n1 && now == 1) return ans = 1;    if(n2 && now == 1) return ans = 0;    if(n2 && now == 2) return ans = 1;    if(sum == 9) return ans = -1; //平局    int win = 0;    for(int i = 0; i < 3; i++) {        for(int j = 0; j < 3; j++) {            if(c[i][j]) continue;            c[i][j] = now;            int nxt = 0;            for(int ii = 0; ii < 3; ii++) {                for(int jj = 0; jj < 3; jj++) {                    nxt = nxt * 3 + c[ii][jj];                }            }            c[i][j] = 0;            int can = dfs(nxt, 3 - now);            if(!can) return ans = 1; //必胜            if(can == -1) win = 1;        }    }    if(!win) return ans = 0; //必败    else return ans = -1;  //平局}int main() {    for(int i = 0; i < maxn; i++) {        for(int j = 0; j < 3; j++) {            dp[i][j] = -2;        }    }    scanf("%d", &T);    while(T--) {        int now = 0;        for(int i = 0; i < 3; i++) {            for(int j = 0; j < 3; j++) {                scanf("%s", s);                int add;                if(s[0] == '.') add = 0;                else if(s[0] == 'x') add = 1;                else add = 2;                now = now * 3 + add;            }        }        scanf("%s", s);        if(s[0] == 'x') st = 1;        else st = 2;        int ans = dfs(now, st);        if(ans ==  0) printf("%c win!\n", st == 1 ? 'o' : 'x');        if(ans ==  1) printf("%c win!\n", st == 2 ? 'o' : 'x');        if(ans == -1) printf("tie!\n");    }    return 0;}


0 0
原创粉丝点击