UVA-1103 Ancient Messages

Ancient Messages(紫书例6-13)

UVA - 1103

给定H行W列的十六进制数据,每个十六进制数表示4位二进制数,由此形成H行W*4列的二进制图,

有6种不同的古代象形文字,在图中以11110000......的形式表现出来,并且与给定的原始图拓扑相等(几个图形,其中每一个可以从其余任一个图形经扭转、弯曲、拉长或收缩得到,而不出现任何点的重叠与断开,它们就是拓扑等价的),

要求识别出图中出现的古代象形文字的种类与个数,并按照字母表顺序输出。

先把16进制数图转换为2进制数图,

再对原图中四边附近的空白部分(0)进行覆盖(-1),

区别六种象形文字的特征量是他们中间的空白部分个数,因此,每用DFS检测到一个象形文字(1),就统计其中空白部分(0)的个数,统计完后都覆盖掉(-1),由此得到每种象形文字的个数,然后按字母表序输出。

坑:输入输出和进制转化比较繁琐,要小心低级错误;

        计数步骤注意细节;

        将图四周的空白部分覆盖时,不要想当然。。。

AC-Code (C++)

Time: 10 ms

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;



const int MAXH = 200 + 10;
int g[MAXH][MAXH];					//保存图
int H, W;							//十六进制图案的行,列
int kase = 1;
int cnt = 0;
int res[6];

bool isin(int x, int y)
{
	return (x >= 0 && x < H && y >= 0 && y < W);
}

int input1[16][4] = { { 0, 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 1, 0 }, { 0, 0, 1, 1 }, 
{ 0, 1, 0, 0 }, { 0, 1, 0, 1 }, { 0, 1, 1, 0 }, { 0, 1, 1, 1 }, 
{ 1, 0, 0, 0 }, { 1, 0, 0, 1 }, { 1, 0, 1, 0 }, { 1, 0, 1, 1 },
{ 1, 1, 0, 0 }, { 1, 1, 0, 1 }, { 1, 1, 1, 0 }, { 1, 1, 1, 1 }
};

char input2[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

char output[6] = { 'A', 'D', 'J', 'K', 'S', 'W' };

//把联通的空白块涂成灰色
void dfs(int x, int y)
{
	if ((!isin(x, y) )|| g[x][y] != 0)
		return;
	g[x][y] = -1;
	dfs(x - 1, y);
	dfs(x + 1, y);
	dfs(x, y - 1);
	dfs(x, y + 1);
}

//把黑块涂成灰色,如果发现白块,计数加一并调用dfs把连通的白块涂成灰色
void dfs2(int x, int y)
{
	if ((!isin(x, y)) || g[x][y] == -1)
		return;
	if (g[x][y] == 0)
	{
		cnt++;
		dfs(x, y);
		return;
	}
	g[x][y] = -1;
	dfs2(x - 1, y);
	dfs2(x + 1, y);
	dfs2(x, y - 1);
	dfs2(x, y + 1);
}


int main(void)
{
	
	while (scanf("%d %d", &H, &W) && H)
	{
		memset(g, 0, sizeof(g));
		memset(res, 0, sizeof(res));
		char str[MAXH];
		for (int i = 0; i < H; i++)
		{
			scanf("%s", str);
			for (int j = 0; j < W; j++)
			{
				char ch = str[j];
				for (int ii = 0; ii < 16; ii++)
				{
					if (ch == input2[ii])
					{
						for (int k = 0; k < 4; k++)
						{
							g[i][j * 4 + k] = input1[ii][k];
						}
					}
				}
			}

		}
		W =W * 4;


               //将图的四周的空白部分都填满
		for (int i = 0; i < H; i++)
		{
			if (g[i][0] == 0)
				dfs(i, 0);
			if (g[i][W - 1] == 0)
				dfs(i, W - 1);
		}

		for (int j = 0; j < W; j++)
		{
			if (g[0][j] == 0)
				dfs(0, j);
			if (g[H - 1][j] == 0)
				dfs(H - 1, j);
		}

		
		for (int i = 0; i < H; i++)
		{
			for (int j = 0; j < W; j++)
			{
				if (g[i][j] == 1)
				{
					cnt = 0;
					dfs2(i, j);
					switch (cnt)
					{
					case 0:res[5]++; break;
					case 1:res[0]++; break;
					case 2:res[3]++; break;
					case 3:res[2]++; break;
					case 4:res[4]++; break;
					case 5:res[1]++; break;
					}
				}
				
			}
		}

		printf("Case %d: ", kase++);
		for (int i = 0; i < 6; i++)
		{
			for (int j = 0; j < res[i]; j++)
			{
				printf("%c", output[i]);
			}
		}
		printf("\n");
		
	}
	
	
	return 0;
}


你可能感兴趣的:(DFS和BFS)