本文主要是介绍围棋(隐藏的BFS),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
围棋
描述:
围棋的棋盘上有19*19条线交织成的361个交点,黑棋和白棋可以下在交点上。我们称这些交点为“目”。
一个目的上下左右四个方向,称之为“气”,如果一个目的四个方向都被某一种颜色的棋子占据,那么即使这个目上并没有棋子,仍然认为这个目被该颜色棋子占据。
如下图中,四个黑棋中心的交点,由于被黑棋包围,因此我们认为这个目属于黑棋,
黑棋拥有4+1=5目
在棋盘的边框地区,只要占据目的三个方向,就可以拥有这个目。
黑棋拥有3+1=4目
同理在棋盘的四个角上,只要占据目的两个气即可。
黑棋拥有2+1=3目
推而广之,当有多个目互相连通的时候,如果能用一种颜色把所有交点的气都包裹住,那么就拥有所有目。
黑棋拥有6+2 = 8目
请编写一个程序,计算棋盘上黑棋和白棋的目数。
输入数据中保证所有的目,不是被黑棋包裹,就是被白棋包裹。不用考虑某些棋子按照围棋规则实际上是死的,以及互相吃(打劫),双活等情况。输入:
第一行,只有一个整数N(1<=N<=100),代表棋盘的尺寸是N * N
第2~n+1行,每行n个字符,代表棋盘上的棋子颜色。
“.”代表一个没有棋子的目
“B”代表黑棋
“W”代表白棋
输出:
只有一行,包含用空格分隔的两个数字,第一个数是黑棋的目数,第二个数是白棋的目数。
样例输入:
4 ..BW ...B .... ....复制
样例输出:
15 1
如果不是出现再BFS专题里,个人觉得还是比较难想到广搜,毕竟前文给出很多包含目的情况。
思路:因为所有的目不是被黑棋包裹,就是被白棋包裹,且不考虑其他情况,所以直接逐个从黑棋进行广度优先遍历,凡是黑棋能到达的目,这个目必属于黑棋;不能到达的则属于白棋。(黑棋不能到达的目一定是被白棋包围了)
注意:1.必须将矩阵全部输入后再对其遍历,逐个从黑棋广搜
2.黑棋到达过的地方不用再搜(book[i][j]=1)
3.每次从黑棋广搜,到达一目即black++;
AC代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;#define x first
#define y secondconst int N=110;
char g[N][N];
int book[N][N];
int black=0,n;
int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
typedef pair<int,int> PII;
PII start,now,ne;void bfs(int xx,int yy)
{queue<PII> q;q.push({xx,yy});book[xx][yy]=1;black++;while(q.size()){now=q.front();q.pop();for(int k=0;k<4;k++){ne.x=now.x+dx[k],ne.y=now.y+dy[k];if(ne.x<0||ne.x>=n||ne.y<0||ne.y>=n) continue;if(book[ne.x][ne.y]||g[ne.x][ne.y]=='W') continue;book[ne.x][ne.y]=1;black++;q.push({ne.x,ne.y});}}
} int main()
{scanf("%d",&n);for(int i=0;i<n;i++){scanf("%s",&g[i]);}for(int i=0;i<n;i++){for(int j=0;j<n;j++){if(!book[i][j]&&g[i][j]=='B') bfs(i,j);}}printf("%d %d",black,n*n-black);return 0;
}
这篇关于围棋(隐藏的BFS)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!