1045: 黑白棋
时间限制: 1 Sec 内存限制: 128 MB
提交: 79 解决: 36
[提交][状态][讨论版]
题目描述
定义一种新的黑白棋:
-
棋盘大小为5*5的格子;
-
有些格子不能放棋子;
-
同一个格子最多放一个棋子;
-
先手执白棋,后手执黑棋;
-
先手第一次可以把棋放在任意可以放的位置上;
-
接下来两人轮流放棋子,这个棋子必须与上一个人放的棋子相邻
请问:两人都是最优策略,是先手赢,还是先手输?
输入
2
11111
11111
11111
11111
00000
11111
11111
11111
11111
10000
输出
win
lose
主要就是利用DFS实现递归查询当前步是不是一定赢,而当前步赢是由后一步一定输来决定的,如果后一步存在一定赢的情况,那么当前状态就一定输了,然后一步步递归得到正确的答案
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int MOD = int(1e9) + 7;
const int INF = 0x3f3f3f3f;
const int fx[] = {-1, 1, 0, 0};
const int fy[] = {0, 0, -1, 1};
const int maxn=7;
int a[maxn][maxn];
bool can(int x,int y){
if(x<0||x>=5||y<0||y>=5||a[x][y]!=0) return false;
else return true;
}
bool dfs(int x,int y){
a[x][y]=1;
for(int i=0;i<4;i++){
int newx=x+fx[i];
int newy=y+fy[i];
if(can(newx,newy)){
if(dfs(newx,newy)){
a[x][y]=0;
return false;//有一个方向当前手的后手赢那么他肯定输
}
}
}
a[x][y]=0;
return true;//如果当前没有可以走的地方或者是可以走的方向他都是赢的话
}
int main(){
int T;
cin >> T;
while(T--){
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
scanf("%1d",&a[i][j]);//这里就实现了只读一位整数
}
}
bool flag=false;
for(int i=0;i<5;i++){
for(int j=0;j<5;j++){
if(can(i,j)){
if(dfs(i,j))
flag=true;//先手只要有一个地方放下去必赢那么肯定就赢了
}
}
}
if(flag) printf("win\n");
else printf("lose\n");
}
return 0;
}