题目大意:
两个人在一个
3×3
的棋盘上分别下
X
和
0
,
X
先
0
后,初始时棋盘为空。如果有
3
个同样的棋子在同一行或同一列或同一斜线,那么游戏结束,该棋子方获胜。
两个人都会用最佳策略。
现在给你一个局面,首先判断是否合法
(
也就是是否可能下得到
分析:
差点又被题目意思给坑了。
就是直接的
SB
博弈搜索,把状态存入
map
中就好了。
AC code:
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <queue>
#include <vector>
#define pb push_back
#define mp make_pair
#define clr(a, b) memset(a, b, sizeof a)
#define rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define per(i, a, b) for(int i = (a); i >= (b); --i)
typedef long long LL;
typedef double DB;
typedef long double LD;
using namespace std;
void open_init()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
ios::sync_with_stdio(0);
}
void close_file()
{
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
}
enum result {lose,win,draw};
string s[3];
map<vector<int>,result> all;
vector<int> g;
bool WIN(vector<int> now)
{
int ret = 0;
rep(i, 0, 2)
ret += now[i]==now[i+3] && now[i+3]==now[i+6] && now[i];
rep(i, 0, 2)
ret += now[i*3]==now[i*3+1] && now[i*3+1]==now[i*3+2] && now[i*3];
ret += now[0]==now[4] && now[4]==now[8] && now[4];
ret += now[2]==now[4] && now[4]==now[6] && now[4];
return ret;
}
int sum0(vector<int> now)
{
int ret = 0;
rep(i, 0, 8) ret += !now[i];
return ret;
}
bool FULL(vector<int> now)
{return !sum0(now);}
result dfs(vector<int> now)
{
if(all.count(now)) return all[now];
if(WIN(now)) return all[now] = lose;
else if(FULL(now)) return all[now] = draw;
int c1 = 0, c2 = 0, c3 = 0, ch = sum0(now)&1?1:-1;
rep(i, 0, 8)
if(!now[i])
{
now[i] = ch;
result tmp = dfs(now);
if(tmp == lose) c1++;
else if(tmp == draw) c2++;
else c3++;
now[i] = 0;
}
if(c1) return all[now] = win;
else if(c2) return all[now] = draw;
else return all[now] = lose;
}
int main()
{
open_init();
dfs(vector<int>(9, 0));
while(cin >> s[0])
{
g.clear();
if(s[0] == "Qc") break;
rep(i, 1, 2) cin >> s[i];
rep(i, 0, 2)
rep(j, 0, 2)
if(s[i][j] == '.') g.pb(0);
else g.pb(s[i][j]=='X'?1:-1);
if(!all.count(g)) puts("Illegal position.");
else
{
result now = all[g];
if(now == draw) puts("Game is a draw.");
else printf("%c wins.\n", sum0(g)&1^now==lose?'X':'0');
}
}
close_file();
return 0;
}