#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;
}
入门经典-6.4图-163-uva1103古代象形符号-四连块,DFS,种子填充,图像识别⭐⭐⭐⭐⭐复杂度:4
最新推荐文章于 2021-08-02 22:50:58 发布