Property Distribution
题目描述
タナカ氏が HW アールの果樹園を残して亡くなりました。果樹園は東西南北方向に H × W の区画に分けられ、区画ごとにリンゴ、カキ、ミカンが植えられています。タナカ氏はこんな遺言を残していました。
果樹園は区画単位でできるだけ多くの血縁者に分けること。ただし、ある区画の東西南北どれかの方向にとなりあう区画に同じ種類の果物が植えられていた場合は、区画の境界が分からないのでそれらは 1 つの大きな区画として扱うこと。
例えば次のような 3 × 10 の区画であれば ('リ’はリンゴ、'カ’はカキ、'ミ’はミカンを表す)
同じ樹がある区画の間の境界を消すと次のようになり、
結局 10 個の区画、つまり 10 人で分けられることになります。*
雪が降って区画の境界が見えなくなる前に分配を終えなくてはなりません。あなたの仕事は果樹園の地図をもとに分配する区画の数を決めることです。
果樹園の地図を読み込み、分配を受けられる血縁者の人数を出力するプログラムを作成してください。
输入
複数のデータセットが与えられます。各データセットは空白で区切られた H, W (H, W ≤ 100) を含む行から始まり、続いて H × W の文字からなる H 行の文字列が与えられます。この文字列には、リンゴを表す ‘@’、カキを表す ‘#’、ミカンを表す '’、の 3 文字しか現れません。*
入力はゼロが2つの行で終わります。データセットの数は 20 を超えません。
输出
各データセットごとに、分配を受ける人数を1行に出力してください。
样例输入
10 10
####*****@
@#@@@@#*#*
@##***@@@*
#****#*@**
##@*#@@*##
*@@@@*@@@#
***#@*@##*
*@@@*@@##@
*@*#*@##**
@****#@@#@
0 0
样例输出
33
题意:
这道题的意思是:给出一个H x W (H,W<=100)的矩阵,求相同符号(共有三种,@#*)连成的区域有几块。输入包含多种数据(不超过20),以输入0 0为结束。
思路:在遍历地图的过程中,利用深搜将相同的符号换成其他符号以做标记,每次从主函数(注意是从主函数)调用深搜的次数就是区域的块数。
代码
#include<iostream>
#include<cstdlib>
using namespace std;
const int maxn = 102;
const int maxm = 102;
int h, w; //行列
char map[maxn][maxm];
int sum; //总数
int dir[4][2] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }; //移动数组
void dfs(int x, int y,char c)
{
map[x][y] = 'a'; //将本位置改为其他符号 用于标记已经访问过
for (int i = 0; i < 4; i++) //遍历上下左右的位置
{
int xx = x + dir[i][0], yy = y + dir[i][1];
if (xx >= 0 && xx < h && yy >= 0 && yy < w && map[xx][yy]==c ) //判断是否越界,是否是同一片区域
{
dfs(xx, yy,c); //深搜 向前走
}
}
return;
}
int main()
{
int i = 0, j = 0; //循环变量
while (cin >> h >> w )
{
if (h == 0 && w == 0)break; //输入0 0退出
for (i = 0; i < h; i++)
{
for (j = 0; j < w; j++)
cin >> map[i][j]; //输入地图
}
for (i = 0; i < h; i++)
{
for (j = 0; j < w; j++) //遍历整个地图
{
if ( map[i][j]!='a' ) //遇到还未标记过的
{
sum++; //总数加1
dfs(i, j,map[i][j]); //找同一个位置的其他坐标
}
}
}
cout << sum << endl;
sum = 0; //要记得在下一组数据输入前重新置0
}
//system("pause");
return 0;
}