Uva1103 World finals 2011——Ancient Messages

这题是2011年的World finals的题目。

判断由01矩阵组成的图像是属于哪个古埃及的文字。从6个图形可以看出,每一个图形里面的  空洞  都是不同的。可以从空洞的个数来判断属于哪个文字。


矩阵组成的每一个文字都是完整的,两个文字之间不会有连接。题目的给是01矩阵每四位构成的十六进制的矩阵,需要转换一下,这个不难。

01矩阵外围再围上一圈 的 0,一开始进行一次深搜dfs(0,0),将每一个文字都分离出来。

再来矩阵中找到 数值为 1 的 地方,从该位置起进行一次深搜,遇到 0,深搜一次,空洞数 + 1。因为第一次深搜 把文字都分离了,所以不会互相干扰。

输出是按字典序输出的。

AC代码:

#include <iostream>
#include <cstring>
using namespace std;

int num[210][210];
int h, w, count;

int ans[8];
char str[] = {'A', 'D', 'J', 'K', 'S', 'W'};
int bin[][4] = {{0,0,0,0},  //0
				{0,0,0,1},  //1
				{0,0,1,0},  //2
				{0,0,1,1},  //3
				{0,1,0,0},  //4
				{0,1,0,1},  //5
				{0,1,1,0},  //6
				{0,1,1,1},  //7
				{1,0,0,0},  //8
				{1,0,0,1},  //9
				{1,0,1,0},  //a
				{1,0,1,1},  //b
				{1,1,0,0},  //c
				{1,1,0,1},  //d
				{1,1,1,0},  //e
				{1,1,1,1}}; //f


bool cheak(int x, int y)
{
	if((x >= 0 && x <= h + 1) && (y >= 0 && y <= w + 1))
		return true;
	else
		return false;
}

void dfs(int x, int y)
{
	if(!cheak(x, y) || num[x][y] != 0)
		return;
	num[x][y] = -1;
//	cout << x << ' ' << y << endl;
	dfs(x - 1, y);
	dfs(x, y + 1);
	dfs(x + 1, y);
	dfs(x, y - 1);
}

void DFS(int x, int y)
{
	if(!cheak(x, y) || num[x][y] == -1)
		return;

	if(num[x][y] == 0)  //找到空洞
	{
		count++;
		dfs(x, y);
		return;
	}
	num[x][y] = -1;
	DFS(x - 1, y);
	DFS(x, y + 1);
	DFS(x + 1, y);
	DFS(x, y - 1);
}

int main()
{
	freopen("1103.txt", "r", stdin);
	int t = 0, i, j;
	char ch;
	while(cin >> h >> w)
	{
		if(h == 0 && w == 0)
			break;
		memset(num, 0, sizeof(num));
		memset(ans, 0, sizeof(ans));
		for(i = 0; i < h; i++)
		{
			for(j = 0; j < w; j++)
			{
				cin >> ch;
				if(ch >= '0' && ch <= '9')      //转换成二进制的
				{
					int l = 0;
					for(int k = j * 4 + 1; k <= j * 4 + 4; k++)
						num[i + 1][k] = bin[ch - '0'][l++];
				} else if(ch >= 'a' && ch <= 'f')
				{
					int l = 0;
					for(int k = j * 4 + 1; k <= j * 4 + 4; k++)
						num[i + 1][k] = bin[ch - 'a' + 10][l++];
				}
			}
		}

		w = w * 4;                   //宽 * 4

		dfs(0, 0);                   //分离文字
		cout << "Case " << ++t << ": ";
		for(i = 1; i <= h; i++)
		{
			for(j = 1; j <= w; j++)
			{
				
				if(num[i][j] == 1)       //找到一个文字
				{
					count = 0;
					DFS(i, j);
					if(count == 0)
						ans[5]++;
					if(count == 1)
						ans[0]++;
					if(count == 2)
						ans[3]++;
					if(count == 3)
						ans[2]++;
					if(count == 4)
						ans[4]++;
					if(count == 5)
						ans[1]++;
				}
				
			}
		}
		for(i = 0; i < 6; i++)
		{
			while(ans[i]--)
				cout << str[i];
		}
		cout << endl;
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值