UVA 1103 Ancient Messages

本文介绍了一种基于图的深度搜索算法的应用案例,通过分析图形中的“洞”数量来解决问题,并详细阐述了如何处理字符‘1’和‘0’以进行有效的计数和遍历。文中提供了一个具体的实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

紫书给出了很好的一种思路,对于题目给出的那些图形,按照这些图形中的“洞”的个数就可以分别,那么利用图的深度搜索就可以了,同时注意要注意如果当前的位置存储的字符是‘1’,如果下一个访问到的字符是‘0’,那么计数就要加1,同时对于0的处理和1的处理是不同的,要设置第三种字符‘-’,表示当前位置已经处理过了,具体的实现见源代码:

#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
using namespace std;

int H, W,cur;
map<char, int> ch2in;
string dict[] = {
	"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011",
	"1100", "1101", "1110", "1111"
};
char area[210][210];
char Flag[] = {'W','A','K','J','S','D'};

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

int dir[4][2] = { 1,0, -1,0, 0,1, 0,-1 };

void dfs1(int x,int y){
	if (!is_true(x, y) || area[x][y] != '0') return;
	area[x][y] = '-';
	for (int i = 0; i < 4; i++){
		dfs1(x+dir[i][0],y+dir[i][1]);
	}
}

void dfs2(int x, int y){
	if (!is_true(x, y) || area[x][y] != '1') return;
	area[x][y] = '-';
	for (int i = 0; i < 4; i++){
		int indexX = x + dir[i][0];
		int indexY = y + dir[i][1];
		if (is_true(indexX, indexY)){
			if (area[indexX][indexY] == '0'){
				cur++;
				dfs1(indexX,indexY);
			}
			else if (area[indexX][indexY] == '1'){
				dfs2(indexX,indexY);
			}
		}
	}
}

int main(){
	int Case = 0;
	while (cin >> H >> W){
		memset(area,'0',sizeof(area));
		if (H == 0 || W == 0) break;
		ch2in.clear();
		W *= 4;
		for (int i = 1; i <= H; i++){
			string s;
			cin >> s;
			string res = "";
			for (int j = 0; j < s.size(); j++){
				int index;
				if (s[j] >= 'a') index = (s[j] - 'a') + 10;
				else index = s[j] - '0';
				res += dict[index];
			}
			memcpy(area[i]+1,res.c_str(),res.size());
		}
		dfs1(0,0);
		for (int i = 1; i <= H; i++){
			for (int j = 1; j <= W; j++){
				if (area[i][j] == '1'){
					cur = 0;
					dfs2(i,j);
					char it = Flag[cur];
					if (ch2in.find(it) == ch2in.end()) ch2in[it] = 1;
					else ch2in[it]++;
				}
			}
		}
		Case++;
		cout << "Case " << Case << ": ";
		for (auto it = ch2in.begin(); it != ch2in.end(); it++){
			while (it->second){
				cout << it->first;
				it->second--;
			}
		}
		cout << endl;
	}
	//system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值