UVA 1103

3 篇文章 0 订阅

一道DFS的题

首先需要将给的16进制数字字符转换为2进制数字字符

个人花费时间较多地方是  如何将多个文字所对应的空洞数与该文字对应上

这里给出一种方法,当然很多大神的题解也写过此方法

1.先给图像数组外围加一圈0,这是为了保证非文字包含的‘0’(背景‘0’),能构成连通块,以方便用dfs给它特异化掉,我是将‘0’换成‘x’

2.遍历图像,一旦找到‘1’(找到某1个文字),就就利用DFS抹掉这个连通块(文字),并在该DFS过程中遇到‘0'时,再另外用一个DFS抹掉文字中的空洞连通块,并计数

3.最后根据得到的空洞数,就可得到对应的输出字符,排序输出即可

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<iostream>
#include<cstdio>
#include<stack>

using namespace std;
#define MAXINDEX 110
#define MAXROW 805
#define MAXCOL 205

char* num_map[MAXINDEX];
char image[MAXROW][MAXCOL];

int dr[] = { -1,1,0,0 };
int dc[] = { 0,0,-1,1 };
char code[] = { 'W','A','K','J','S','D' };
int row, col;
string buf;
void init_map()//构建16进制与2进制编码映射
{
	num_map['0'] = "0000";
	num_map['1'] = "0001";
	num_map['2'] = "0010";
	num_map['3'] = "0011";
	num_map['4'] = "0100";
	num_map['5'] = "0101";
	num_map['6'] = "0110";
	num_map['7'] = "0111";
	num_map['8'] = "1000";
	num_map['9'] = "1001";
	num_map['a'] = "1010";
	num_map['b'] = "1011";
	num_map['c'] = "1100";
	num_map['d'] = "1101";
	num_map['e'] = "1110";
	num_map['f'] = "1111";
}
class _pair
{
public:
	int _r;
	int _c;
	_pair(int r, int c) :_r(r), _c(c){}
	_pair next(int dir) const
	{
		return _pair(this->_r + dr[dir], this->_c + dc[dir]);
	}
};
bool is_inside(const _pair &pair)//在图像外围加了一圈0(右边和下边),使得非文字的背景0能构成连通块,因此限制范围加1即可
{
	return pair._r >= 0 && pair._r <= row + 1 && pair._c >= 0 && pair._c <= 4 * col + 1;
}

void dfs_background(const _pair &start)
{
	stack<_pair> _stack;
	_stack.push(start);
	while (!_stack.empty())
	{
		_pair cur = _stack.top();
		_stack.pop();
		image[cur._r][cur._c] = 'x';//将文字背景特征化

		for (int i = 0;i != 4;++i)
		{
			_pair next = cur.next(i);
			if (is_inside(next) && image[next._r][next._c] == '0')
			{
				_stack.push(next);
			}
		}
	}
}
void dfs_word(const _pair &start, int &count)
{
	bool flag = false;
	stack<_pair> _stack;
	_stack.push(start);
	while (!_stack.empty())
	{
		_pair cur = _stack.top();
		_stack.pop();
		image[cur._r][cur._c] = 'x';//文字中的空洞标记为已访问

		for (int i = 0;i != 4;++i)
		{
			_pair next = cur.next(i);
			if (is_inside(next) && image[next._r][next._c] == '0')
			{
				_stack.push(next);
				flag = true;//标记为发现空洞
			}
		}
	}
	if (flag)
	{
		++count;
	}
}
void dfs(const _pair &start, int &count)
{
	stack<_pair> _stack;
	_stack.push(start);
	while (!_stack.empty())
	{
		_pair cur = _stack.top();
		image[cur._r][cur._c] = 'x';
		_stack.pop();

		for (int i = 0;i != 4;++i)
		{
			_pair next = cur.next(i);
			if (is_inside(next) && image[next._r][next._c] == '1')
			{
				dfs_word(next, count);
				_stack.push(next);
			}
		}
	}
}
void init_decode()//在图像外围加了一圈0(左边和上边),使得非文字的背景0能构成连通块
{
	for (int i = 0;i != row;++i)
	{
		cin >> buf;
		for (int j = 0;j != col;++j)
		{
			image[i + 1][4 * j + 1] = num_map[buf[j]][0];
			image[i + 1][4 * j + 2] = num_map[buf[j]][1];
			image[i + 1][4 * j + 3] = num_map[buf[j]][2];
			image[i + 1][4 * j + 4] = num_map[buf[j]][3];
		}
	}
}

int main()
{
	int n = 0;
	init_map();
	while (1)
	{
		memset(image, '0', sizeof(image));
		cin >> row >> col;
		if (!row && !col)
		{
			break;
		}
		int colsum = 4 * col;
		++n;
		init_decode();
		dfs_background(_pair(0, 0));
		string codes;
		for (int i = 0;i != row;++i)
		{
			for (int j = 0;j != colsum;++j)
			{
				if (image[i][j] == '1')
				{
					int cnt = 0;
					dfs(_pair(i, j), cnt);
					codes += code[cnt];
				}
			}
		}
		sort(codes.begin(), codes.end());
		printf("Case %d: %s\n", n, codes.c_str());
	}
	return 0;
}
虽说是非递归的DFS,但是速度不是很快,在UVA上是0.049s,我找了一个递归的DFS,速度0.019,相比慢了很多。

理论来说非递归要比递归要快一些,可能是因为构造函数拖慢了速度。

如果有大神知道哪里是速度瓶颈,请多多指教



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值