[题解]UVA12987 Ancient Go

题意

现在有两个人 AB 在下古代围棋,A 执黑,B 执白。(黑棋用 x 表示,白棋用 o 表示,没子的点用 . 表示)

规则如下:

  • 棋盘大小为 9×9
  • 如果任意一个同色的连通块四周没有任何空着没子的点,那么,这个连通块的子都会死掉,移出棋局。

现在给你一个下过的棋局,问:当前 A 能否只下一颗子,使得 B 至少死掉一颗子。

思路

一个很简单的搜索,首先你可以直接搜索连通块,在搜索的过程中算出连通块四周的空格数量。如果这个连通块周围空格的数量恰好为 1,则这颗棋就能下在此位置,所以成立。

但是,这道题有一个坑,就是你算空格数量的时候必须判重加标记,因为遇到“凹”字型的情况,就会有一个点被多算一次,导致出错。(如图)

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 国际」许可协议进行许可。

posted @   WBIKPS  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示