Property Distribution Aizu - 0118

3 篇文章 0 订阅

タナカ氏が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

 

题目大意:

Descriptions:

在H * W的矩形果园里有苹果、梨、蜜柑三种果树, 相邻(上下左右)的同种果树属于同一个区域,给出果园的果树分布,求总共有多少个区域。 

Input

多组数据,每组数据第一行为两个整数H、W(H <= 100, W <= 100), H =0 且 W = 0代表输入结束。以下H行W列表示果园的果树分布, 苹果是@,梨是#, 蜜柑是*。

Output

对于每组数据,输出其区域的个数

 

AC代码:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

char MAP[105][105];
int vis[105][105];
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};//方向向量
int h,w,sum;

void dfs(int x,int y,char ch){//苹果是@ 
	if(vis[x][y]){
		return;
	}
	vis[x][y] = 1;
	int xx,yy;//下一步 
	for(int i=0; i<4; i++){
		xx = x + dir[i][0];
		yy = y + dir[i][1];//不要把y写成x
		
		if(!vis[xx][yy] && MAP[xx][yy] == ch){
			dfs(xx,yy,ch);
		}
	}	
}

int main(void)
{
	while(cin>>h>>w && h && w){
		memset(vis,0,sizeof(vis));
		memset(MAP,'X',sizeof(MAP));
		sum = 0;
		for(int i=0; i<h; i++){
			for(int j=0; j<w; j++){
				cin >> MAP[i][j];
			}
		}
		
		for(int i=0; i<h; i++){
			for(int j=0; j<w; j++){
				if(!vis[i][j] && MAP[i][j] != 'X'){
					sum++;
					dfs(i,j,MAP[i][j]);
				}
			}
		}
		
		cout << sum << endl;
		
	}
	return 0;
}

版本二:

#include <iostream>

using namespace std;

char MAP[105][105];
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};//方向向量
int h,w,sum;

void dfs1(int x,int y){//苹果是@ 
	MAP[x][y] = '.';
	int xx,yy;
	for(int i=0; i<4; i++){
		xx = x + dir[i][0];
		yy = y + dir[i][1];
		
		if(MAP[xx][yy]=='@' && xx>=0 && xx<h && yy>=0 && yy<w){
			MAP[xx][yy] = '.';
			dfs1(xx,yy);
		}
	}
	
}
 
void dfs2(int x,int y){//梨是# 
	MAP[x][y] = '.';
	int xx,yy;
	for(int i=0; i<4; i++){
		xx = x + dir[i][0];
		yy = y + dir[i][1];
		
		if(MAP[xx][yy]=='#' && xx>=0 && xx<h && yy>=0 && yy<w){
			MAP[xx][yy] = '.';
			dfs2(xx,yy);
		}
	}
	
}
 
void dfs3(int x,int y){//蜜桔是* 
	MAP[x][y] = '.';
	int xx,yy;
	for(int i=0; i<4; i++){
		xx = x + dir[i][0];
		yy = y + dir[i][1];
		
		if(MAP[xx][yy]=='*' && xx>=0 && xx<h && yy>=0 && yy<w){
			MAP[xx][yy] = '.';
			dfs3(xx,yy);
		}
	}
	
}

int main(void)
{
	while(cin>>h>>w && h && w){
		sum = 0;
		for(int i=0; i<h; i++){
			for(int j=0; j<w; j++){
				cin >> MAP[i][j];
			}
		}
		
		for(int i=0; i<h; i++){
			for(int j=0; j<w; j++){
				if(MAP[i][j] == '@'){
					dfs1(i,j);
					sum++;
				}else if(MAP[i][j] == '#'){
					dfs2(i,j);
					sum++;
				}else if(MAP[i][j] == '*'){
					dfs3(i,j);
					sum++;
				}
			}
		}

		cout << sum << endl;
		
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值