链接
题意
8x8的围棋,x为黑, o为白,当前下黑子能否至少提出一颗白子
思路
其实这题没必要写一篇博客的,是简单的模拟。可是近段时间对围棋比较感兴趣吧,印象中这是第一次写围棋相关的题目,正好AlphaGo现在正在舆论的风口浪尖,所以还是留存一下此题吧。
代码
#include <bits/stdc++.h>
#define LL long long
#define MAXN 15
using namespace std;
const int step[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
struct Node{
int x, y;
};
int a[MAXN][MAXN];
char ss[MAXN][MAXN];
bool vis[MAXN][MAXN], mp[MAXN][MAXN];
bool done[105], is_die[105];
void bfs(int p, int q, int flag){
queue<Node> Q;
Node s, t;
s.x = p;
s.y = q;
Q.push(s);
a[p][q] = flag;
while(!Q.empty()){
s = Q.front(), Q.pop();
for(int i = 0; i < 4; ++i){
t.x = s.x + step[i][0];
t.y = s.y + step[i][1];
if(t.x < 1 || t.x > 9 || t.y < 1 || t.y > 9) continue;
if(ss[t.x][t.y] == '.' || ss[s.x][s.y] != ss[t.x][t.y]) continue;
if(vis[t.x][t.y]) continue;
Q.push(t);
vis[t.x][t.y] = true;
a[t.x][t.y] = flag;
}
}
}
int find_eye(int p, int q){
queue<Node> Q;
memset(mp, 0, sizeof(mp));
Node s, t;
s.x = p;
s.y = q;
Q.push(s);
mp[p][q] = true;
int res = 0;
while(!Q.empty()){
s = Q.front(), Q.pop();
for(int i = 0; i < 4; ++i){
t.x = s.x + step[i][0];
t.y = s.y + step[i][1];
if(t.x < 1 || t.x > 9 || t.y < 1 || t.y > 9 || mp[t.x][t.y]) continue;
mp[t.x][t.y] = true;
if(ss[t.x][t.y] == '.'){
++res;
continue;
}
if(ss[t.x][t.y] == ss[s.x][s.y]){
Q.push(t);
}
}
}
return res;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
int T;
int cas = 0;
scanf("%d", &T);
while(T--){
for(int i = 1; i <= 9; ++i){
scanf("%s", ss[i] + 1);
}
//找出连通块
memset(vis, 0, sizeof(vis));
int flag = 1;
for(int i = 1; i <= 9; ++i){
for(int j = 1; j <= 9; ++j){
if(!vis[i][j] && ss[i][j] != '.'){
bfs(i, j, flag++);
}
//printf("%5d", a[i][j]);
}
// printf("\n");
}
//提对方死棋
memset(done, 0, sizeof(done));
for(int i = 1; i <= 9; ++i){
for(int j = 1; j <= 9; ++j){
if(is_die[a[i][j]]){
ss[i][j] = '.';
continue;
}
if(done[a[i][j]]) continue;
if(ss[i][j] != 'o') continue;
int num = find_eye(i, j);
done[a[i][j]] = true;
if(num == 0){
is_die[a[i][j]] = true;
ss[i][j] = '.';
}
}
}
//提己方死棋
memset(done, 0, sizeof(done));
for(int i = 1; i <= 9; ++i){
for(int j = 1; j <= 9; ++j){
if(is_die[a[i][j]]){
ss[i][j] = '.';
continue;
}
if(done[a[i][j]]) continue;
if(ss[i][j] != 'x') continue;
int num = find_eye(i, j);
done[a[i][j]] = true;
if(num == 0){
is_die[a[i][j]] = true;
ss[i][j] = '.';
}
}
}
//提子后计算对方气
memset(done, 0, sizeof(done));
bool ans = false;
for(int i = 1; i <= 9; ++i){
for(int j = 1; j <= 9; ++j){
if(done[a[i][j]]) continue;
if(ss[i][j] != 'o') continue;
int num = find_eye(i, j);
done[a[i][j]] = true;
if(num == 1){
ans = true;
break;
}
}
if(ans) break;
}
if(ans){
printf("Case #%d: Can kill in one move!!!\n", ++cas);
}
else{
printf("Case #%d: Can not kill in one move!!!\n", ++cas);
}
}
}