hdu 1198

本文介绍了一个用于计算图像中连通分量数量的算法,通过矩阵表示和深度优先搜索实现。代码示例清晰地展示了如何初始化矩阵、根据字母调整矩阵以及计算连通分量数。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include  <cstring>

using namespace std;

//本题显然是一个求连通分量数的一个题目,关键是如何处理字母所对应的图像,这里采用点对*3的矩阵
const static int M = 455;
//const static int MM = 55;

int map[M][M];
int ans = 0;
int n,m;
int dist[4][2]={-1,0,0,-1,1,0,0,1};

void deal(int x,int y)//初始化以(x,y)为左上角的*3矩阵
{
	for(int i=x;i<x+3;i++)
		for(int j=y;j<y+3;j++)
			map[i][j]=0;
	map[x+1][y+1]=1;
	return ;
}

void pre_map(int x,int y,char ch)//根据字母调节以(x,y)为左上角的*3矩阵,对应图片中有则用标志
{
	deal(x,y);
	switch(ch)
	{
	case 'A':map[x+1][y]=1;map[x][y+1]=1;break;
	case 'B':map[x][y+1]=1;map[x+1][y+2]=1;break;
	case 'C':map[x+1][y]=1;map[x+2][y+1]=1;break;
	case 'D':map[x+1][y+2]=1;map[x+2][y+1]=1;break;
	case 'E':map[x][y+1]=1;map[x+2][y+1]=1;break;
	case 'F':map[x+1][y]=1;map[x+1][y+2]=2;break;
	case 'G':map[x+1][y]=1;map[x][y+1]=1;map[x+1][y+2]=1;break;
	case 'H':map[x+1][y]=1;map[x][y+1]=1;map[x+2][y+1]=1;break;
	case 'I':map[x+2][y+1]=1;map[x+1][y]=1;map[x+1][y+2]=2;break;;
	case 'J':map[x+1][y+2]=1;map[x][y+1]=1;map[x+2][y+1]=1;break;
	case 'K':map[x][y+1]=1;map[x+2][y+1]=1;map[x+1][y]=1;map[x+1][y+2]=2;break;

	}
	return ;
}

void init_map()//初始化图像
{
	for(int i=0;i<n*3;i+=3)
	{		for(int j=0;j<3*m;j+=3)
	{
		char ch;
		cin>>ch;
		pre_map(i,j,ch);
	}
	getchar();
	}
}

void print()//为验证图像是否正确的一个函数
{
	for(int i=0;i<3*n;i++)
	{
		for(int j=0;j<3*m;j++)
		{
			if(map[i][j]==0) cout<<"0";
			else cout<<"*";
		}
		cout<<endl;
	}
}

void dfs(int x,int y)//求某点的连通分量,并全部标记为
{
	if(map[x][y]==0) return ;
	else
	{
		map[x][y]=0;
		for(int i=0;i<4;i++)
		{
			int a=x+dist[i][0];
			int b=y+dist[i][1];
			if(a>=0&&b>=0&&a<3*n&&b<3*m)
				dfs(a,b);
		}
	}

}

bool init()//主操作函数
{
	cin>>n>>m;
	if(n==-1&&m==-1)
		return false;
	init_map();
	//print();
	ans = 0;
	for(int i=0;i<3*n;i++)
		for(int j=0;j<3*m;j++)
			if(map[i][j]==1) {ans++;dfs(i,j);}
			cout<<ans<<endl;
			return true;
}

int main()
{
	while(init());
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值