用DFS求连通块进阶

UVA-1103(Ancient Messages,World Finals)
点击看图
输入H行W列的字符矩阵(H<=200, W<=50)
每个字符都是16进制数字,将他们转化为二进制后产生的图形中有'1'和'0',构成上面的图形。
根据符号内部白色洞的数量来判断。

#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 1e2 * 2 + 10;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
char pic[maxn][maxn];
int pic1[maxn][maxn], idx[maxn][maxn];

char *bin[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111"
               ,"1000","1001", "1010", "1011", "1100", "1101", "1110", "1111"};
               
char code[] = "WAKJSD";
int h, w;
void init(){
	memset(idx, 0, sizeof idx);
	memset(pic1, 0, sizeof pic1);
	for(int i = 0; i < h; ++i){
		for(int j = 0; j < w; ++j){
			if(isdigit(pic[i][j]))
				pic[i][j] -= '0';
			else
				pic[i][j] -= 'a'-10;
			for(int k = 0; k < 4; ++k)
				pic1[1+i][1+j*4+k] = bin[pic[i][j]][k] - '0';//在这里将原来的图形外围补一圈0,确保外围同色 
		}
	}
} 

int dfs(int r, int c, int id){
	if	return;
	if(idx[r][c] != 0)	return;
	idx[r][c] = id;
	for(int i = 0; i < 4; ++i){
		int rr = r+dx[i], cc = c+dy[i];
		if(pic[r][c] == pic[rr][cc] && (rr >= h || rr <= 0 || cc >= w || cc <= 0)
		 && idx[rr][cc] != 0)
			dfs(rr, cc, id);
	}
}

int main(){
	while(scanf("%d %d", &h, &w) == 2 && h && w){
		for(int i = 0; i < h; ++i)	scanf(" %s", pic[i]);
		init();
		h += 2;
		w = w*4 + 2;
		int cnt = 0;
		vector<int> ccc;
		for(int i = 0; i < h; ++ i){
			for(int j = 0; j < w; ++j){
				if(!idx[i][j]){
                    dfs(i,j,++cnt);
                    if(pic1[i][j] == 1) ccc.push_back(cnt);
                }
            }
        }
        vector<set<int> > neigh(cnt+1);
        for(int i = 0; i < H; ++i){
            for(int j = 0; j < W; ++j){
               if(pic[i][j]){
                    for(int k = 0; k < 4; ++k){
                        int x = i + dx[k], y = j + dy[k];
                        if(x >= 0 && x < H && y >= 0 && y < W &&
                           pic[x][y] == 0 && color[x][y] != 1)
                            neigh[color[i][j]].insert(color[x][y]);
                    }
                }
            }
        }
 
        vector<char> ans;
        for(int i = 0, sz = cc.size(); i < sz; ++i)
            ans.push_back(code[neigh[cc[i]].size()]);
        sort(ans.begin(),ans.end());
 
        printf("Case %d: ",cas++);
        for(int i = 0, sz = ans.size(); i < sz; ++i)
            printf("%c",ans[i]);
        puts("");
	}
	return 0;
}

上一篇:爬取B站up主相册原图


下一篇:上传到HDFS上的文件遇到乱码问题