[题解]UVA12987 Ancient Go
题意
现在有两个人 A
和 B
在下古代围棋,A
执黑,B
执白。(黑棋用 x
表示,白棋用 o
表示,没子的点用 .
表示)
规则如下:
- 棋盘大小为 。
- 如果任意一个同色的连通块四周没有任何空着没子的点,那么,这个连通块的子都会死掉,移出棋局。
现在给你一个下过的棋局,问:当前 A
能否只下一颗子,使得 B
至少死掉一颗子。
思路
一个很简单的搜索,首先你可以直接搜索连通块,在搜索的过程中算出连通块四周的空格数量。如果这个连通块周围空格的数量恰好为 ,则这颗棋就能下在此位置,所以成立。
但是,这道题有一个坑,就是你算空格数量的时候必须判重加标记,因为遇到“凹”字型的情况,就会有一个点被多算一次,导致出错。(如图)
Code
#include <bits/stdc++.h>
#define re register
using namespace std;
int T;
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
char c[15][15];
bool vis[15][15],falg[15][15];
inline void dfs(int x,int y,int &res){
if (!falg[x - 1][y] && c[x - 1][y] == '.'){//判断空格
falg[x - 1][y] = true;
res++;
}
if (!falg[x + 1][y] && c[x + 1][y] == '.'){
falg[x + 1][y] = true;
res++;
}
if (!falg[x][y - 1] && c[x][y - 1] == '.'){
falg[x][y - 1] = true;
res++;
}
if (!falg[x][y + 1] && c[x][y + 1] == '.'){
falg[x][y + 1] = true;
res++;
}
for (re int i = 0;i <= 3;i++){//继续向下搜索
int tx = x + dx[i];
int ty = y + dy[i];
if (!vis[tx][ty] && c[tx][ty] == 'o'){
vis[tx][ty] = true;
dfs(tx,ty,res);
}
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> T;
for (re int opt = 1;opt <= T;opt++){
bool flag = false;
memset(vis,false,sizeof vis);//多测清空
for (re int i = 1;i <= 9;i++){
for (re int j = 1;j <= 9;j++) cin >> c[i][j];
}
for (re int i = 1;i <= 9 && !flag;i++){
for (re int j = 1;j <= 9 && !flag;j++){
if (c[i][j] == 'o' && !vis[i][j]){
memset(falg,false,sizeof(falg));//标记空格
int f = 0;//空格数量
dfs(i,j,f);
if (f == 1){
flag = true;
break;
}
}
}
}
if (flag) printf("Case #%d: Can kill in one move!!!\n",opt);
else printf("Case #%d: Can not kill in one move!!!\n",opt);
}
return 0;
}
作者:WaterSun
出处:https://www.cnblogs.com/WaterSun/p/18270911
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】