围棋的块数

/*
	Name: 围棋数子 
	Copyright: free 
	Author: 巧若拙 
	Date: 16-07-17 13:57
	Description: 围棋数子
描述:给定一个n*n的围棋盘,交叉点上分布着黑,白子或空白(分别用字符b,w和 n表示),
相同颜色的棋子在同行或同列相连属于同一块棋,请遍历整个围棋盘,计算黑白棋各有几块。
输入:第一行只有一个整数n(0<n<20),表示棋盘的大小。
接下来n行中,包含n个字符,分别用字符b,w和 n表示黑,白子或空白。
输出:两个整数,分别表示黑,白棋各有几块。 
样例输入: 
6
bbbnww
nbnnwn
bbwwnn
bwwnnw
bbbbww
wwnbbw
样例输出
1 4

算法思想:深搜或广搜均可 
*/
#include<iostream>
#include<cstdio>

using namespace std;

const int MAX = 20; 
char map[MAX][MAX];
bool lib[MAX][MAX]; //标记该点是否已经来过 
int DicX[4] = {0, 1, 0, -1}; //向东南西北四个方向移动,x坐标相当于行坐标 
int DicY[4] = {1, 0, -1, 0}; //向东南西北四个方向移动,y坐标相当于列坐标 
int n;

void DFS(int x, int y, char c); //x和y分别表示当前行坐标和列坐标,c表示棋子颜色 
void BFS(int x, int y, char c); //x和y分别表示当前行坐标和列坐标,c表示棋子颜色

int main() 
{
	cin >> n;
    for (int i=0; i<n; i++)
	{
		for (int j=0; j<n; j++)
		{
			cin >> map[i][j];
		}
	}
	
	int sumB = 0, sumW = 0; //分别记录黑,白棋的块数 
	for (int i=0; i<n; i++)
	{
		for (int j=0; j<n; j++)
		{
			if (!lib[i][j] && map[i][j] != 'n') //该位置未处理过
			{
			//	DFS(i, j, map[i][j]);
			    BFS(i, j, map[i][j]);
				
				if (map[i][j] == 'b')
					sumB++;
				else	
					sumW++;
			} 
		}
	}
	cout << sumB << " " << sumW << endl;
	
    return 0;
}

void DFS(int x, int y, char c) //x和y分别表示当前行坐标和列坐标,c表示棋子颜色 
{
	int nx, ny;
	for (int i=0; i<4; i++)
	{
		nx = x + DicX[i];
	    ny = y + DicY[i];
		if (nx >= 0 && nx < n && ny >= 0 && ny < n && !lib[nx][ny] && map[nx][ny] == c)
		{
			lib[nx][ny] = 1; //走过了就不能再来 
			DFS(nx, ny, c);
		}
	}
}

void BFS(int x, int y, char c) //x和y分别表示当前行坐标和列坐标,c表示棋子颜色 
{
	int Q[MAX*MAX][2]; //用来存储节点坐标的队列 
	int nx, ny, r = 0, f = 0;
	
	Q[r][0] = x;
	Q[r++][1] = y;
	
	while (r > f)
	{
		x = Q[f][0];
		y = Q[f++][1];
		for (int i=0; i<4; i++)
		{
			nx = x + DicX[i];
		    ny = y + DicY[i];
			if (nx >= 0 && nx < n && ny >= 0 && ny < n && !lib[nx][ny] && map[nx][ny] == c)
			{
				lib[nx][ny] = 1; //走过了就不能再来 
				Q[r][0] = nx;
				Q[r++][1] = ny;
			}
		}
	}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值