入门经典-6.4图-163-uva1103古代象形符号-四连块,DFS,种子填充,图像识别⭐⭐⭐⭐⭐复杂度:4

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
using namespace std;
const int maxh=200+10;
const int maxw=50*4+10;
char bin[256][5];//映射:将一个十六进制数字映射成四个二进制数字 (字符类型 转换int要减去'0')
int pic[maxh][maxw],H,W,color[maxh][maxw];
char line[maxw];//类型为char 

void decode(char ch,int row,int col){
	for(int i=0;i<4;i++){
		pic[row][col+i]=bin[ch][i]-'0';//不要忘记-'0' 
	}
}

const int dr[]={0,0,1,-1};
const int dc[]={-1,1,0,0}; 

void dfs(int row,int col,int c){
	color[row][col]=c;
	for(int i=0;i<4;i++){
		int row2=row+dr[i];
		int col2=col+dc[i];
		if(row2>=0&&row2<H&&col2>=0&&col2<W&&pic[row2][col2]==pic[row][col]&&color[row2][col2]==0)
		//在边界内 且属于相同类型 且未涂色 
		dfs(row2,col2,c);
	}
}


vector<set<int> > neighbors;

void check_neighbors(int row,int col){
	for(int i=0;i<4;i++){
		int row2=row+dr[i];
		int col2=col+dc[i];
		if(row2>=0&&row2<H&&col2>=0&&col2<W&&color[row2][col2]!=1&&pic[row2][col2]!=1)
		//讲在边界内 且不是背景 且不是轮廓 的方块颜色加入相应字符颜色编号的颜色集合中 
		neighbors[color[row][col]].insert(color[row2][col2]);
	}
}


//将不同象形字轮廓的颜色编号转换到对应象形字编号 
const char* code="WAKJSD";
char recognize(int c){
	int cnt=neighbors[c].size();
	return code[cnt];
}
int main(){
	strcpy(bin['0'],"0000");
	strcpy(bin['1'],"0001");
	strcpy(bin['2'],"0010");
	strcpy(bin['3'],"0011");
	strcpy(bin['4'],"0100");
	strcpy(bin['5'],"0101");
	strcpy(bin['6'],"0110");
	strcpy(bin['7'],"0111");
	strcpy(bin['8'],"1000");
	strcpy(bin['9'],"1001");
	strcpy(bin['a'],"1010");
	strcpy(bin['b'],"1011");
	strcpy(bin['c'],"1100");
	strcpy(bin['d'],"1101");
	strcpy(bin['e'],"1110");
	strcpy(bin['f'],"1111");
    
	int kase=0;
	while(cin>>H>>W&&H){
		memset(pic,0,sizeof(pic));
		for(int i=0;i<H;i++){
			cin>>line;
			for(int j=0;j<W;j++){
				decode(line[j],i+1,j*4+1); 
			}
		}
		
		H+=2;  //上下左右各增一行空白边界  空白边界颜色为1  因为dfs从(0,0)开始 初始cnt为1
		//即字母背景色为1 
		W=W*4+2;
		
		int cnt=0;
		vector<int> cc;//存放pic=1的颜色值 即不同象形字轮廓的颜色值 不同轮廓对应一个不同的颜色值 
		memset(color,0,sizeof(color));
		for(int i=0;i<H;i++){
			for(int j=0;j<W;j++){
				if(!color[i][j]){//选取未涂色连通块 
					dfs(i,j,++cnt);
				    if(pic[i][j]==1)
				    cc.push_back(cnt);
				}
				
			}
		}
		
		neighbors.clear();
		neighbors.resize(cnt+1);
		for(int i=0;i<H;i++){
			for(int j=0;j<W;j++){
				if(pic[i][j]==1)
				check_neighbors(i,j);
			}
		}
		
		vector<char> ans;
		for(int i=0;i<cc.size();i++)
		ans.push_back(recognize(cc[i]));
		sort(ans.begin(),ans.end());
		
		printf("Case %d: ",++kase);
		for(int i=0;i<ans.size();i++) printf("%c",ans[i]);
		cout<<endl;
	} 
	return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_41093189/article/details/79595648