UVa 1103 - Ancient Messages (染色+dfs)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstdlib>
#include<stack>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<sstream>
#include<utility>
#include<ctype.h>
#define f(i, a, b) for(int i=a; i<b; i++)
#define rf(i, a, b) for(int i=a; i>=b; i--)
#define uf(i, a, b) for(i=a; i<b; i++)
#define urf(i, a, b) for(i=a; i>=b; i--)
#define cl(a, b) memset(a, b, sizeof(a))
#define pi acos(-1.0)
#define sm 1e-10
#define inf 1e9
#define inf64 1e16
#define ll long long
using namespace std;
typedef pair<int,int> Pair;

/* G++ 5.1.0 */
int pic[210][210];
int id[210][210];
int bin[16][4];
bool vis[210][210];
int n, m;
int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
char hol[6] = {'W','A','K','J','S','D'};

void setbin() {
	f(i, 0, 16) {
		int x = i;
		rf(j, 3, 0) bin[i][j] = (x&1), x >>=1;
	}
}

void dfs1(int x, int y, int mem, int id1) {
	if(x<0||x>=(n+2)||y<0||y>=(4*m+2)) return;
	if(vis[x][y]||pic[x][y]!=mem) return;
	vis[x][y] = true;
	id[x][y] = id1;
	f(i, 0, 4) 
		dfs1(x+dir[i][0],y+dir[i][1], mem, id1);
}

void dfs2(int x, int y, int id1) {
	if(id[x][y]!=0) return;
	id[x][y] = id1;
	f(i, 0, 4)
		dfs2(x+dir[i][0], y+dir[i][1], id1);
}

int main() {
	setbin();
	int kase = 1;
	while(scanf("%d %d", &n, &m) && n) {
		cl(pic, 0);
		f(i, 1, n+1) {
			char line[55];
			scanf("%s", line+1);
			f(j, 1, m+1) {
				char c = line[j];
				f(z, 0, 4) pic[i][4*j-3+z] = bin[c>='a'?(c-'a'+10):(c-'0')][z];
			}
		} //将整个图用1,0表示,,并向外扩充一格 
		
		cl(vis, false);
		cl(id, 0);
		dfs1(0, 0, 0, -1); // 将外围的“白点”除掉 
		
		int cnt = 1;
		f(i, 1, n+1) {
			f(j, 1, 4*m+1) {
				if(pic[i][j]==1&&!id[i][j]) dfs1(i, j, 1, cnt++);
			}
		}//给不同的符号染色 
		
		int num[cnt+1];
		cl(num, 0);
		
		int cur;
		f(i, 1, n+1) {
			f(j, 1, 4*m+1) {
				if(id[i][j]!=-1&&id[i][j]!=0) cur = id[i][j]; else //用cur标记符号id 
				if(id[i][j]==0) {
					dfs2(i, j, cur);
					num[cur] ++;
				}
			}
		}//找洞 
		
//		f(i, 0, n+2) {
//			f(j, 0, 4*m+2) {
//				printf("%3d", id[i][j]);
//			}
//			printf("\n");
//		}
		
		char res[55];
		printf("Case %d: ", kase++);
		f(i, 1, cnt) res[i] = hol[num[i]]; sort(res+1, res+cnt);
		f(i, 1, cnt) printf("%c", res[i]); printf("\n");
	}
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值