这题剥去洋洋洒洒的体面,就是求连通块个数,和连通块里空白区域的个数,最后判断是哪个象形字,好有创意。
题意:给你象形字的图形,给你一个01矩阵,拓扑等价画出这些象形字,判断图中 有哪些象形字。
思路:观察可以发现,每个象形字的空白块数是不同的,因此用dfs求出每个象形区域的联通块数就可以判断是那个字,按照字典序输出。
最初,我在想怎么找到恰好每个字的范围才能找它里面有多少空白区域。所以这里有两个dfs,一个把字以外的区域-1化,一个在字里找空白个数。这题还有一点16进制转二进制简单字符串处理。
详见代码。
#include <fstream> #include <iostream> #include <string> #include <cstring> #include <complex> #include <math.h> #include <set> #include <vector> #include <map> #include <queue> #include <stdio.h> #include <stack> #include <algorithm> #include <list> #include <ctime> #include <ctime> #include <assert.h> #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second #define eps 1e-8 #define M_PI 3.141592653589793 typedef long long ll; const ll mod=1000000007; const int inf=0x7fffffff; ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} using namespace std; char res[]={'A','D','J','K','S','W'}; char str[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; int s[16][4]= { {0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1}, {0,1,0,0},{0,1,0,1},{0,1,1,0},{0,1,1,1}, {1,0,0,0},{1,0,0,1},{1,0,1,0},{1,0,1,1}, {1,1,0,0},{1,1,0,1},{1,1,1,0},{1,1,1,1} }; int num[6]; int M[250][250],n,m,cnt; bool in_M(int x,int y) { return (x>=0&&y>=0&&x<=n+1&&y<=m+1); } void dfs(int x,int y) { if(!in_M(x,y)||M[x][y]!=0) return; M[x][y]=-1; dfs(x+1,y);dfs(x-1,y);dfs(x,y+1);dfs(x,y-1); } void dfs2(int x,int y) { if(!in_M(x,y)||M[x][y]==-1) return; if(M[x][y]==0){ cnt++; dfs(x,y); return; } M[x][y]=-1; dfs2(x-1,y);dfs2(x+1,y);dfs2(x,y+1);dfs2(x,y-1); } int main() { int t=0; while(scanf("%d %d",&n,&m)){ getchar(); if(n==0&&m==0) return 0; //cout<<n<<m<<endl; memset(num,0,sizeof(num)); memset(M,0,sizeof(M)); for(int i=1;i<=n;i++){ int len=1; for(int j=1;j<=m;j++){ char c;scanf("%c",&c); for(int k=0;k<16;k++){ if(str[k]==c){ for(int l=0;l<4;l++){ M[i][len++]=s[k][l]; } break; } } } getchar(); } m*=4; dfs(0,0); /* cout<<n<<m<<endl; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cout<<M[i][j]; } cout<<endl; } cout<<"ok"<<endl; */ for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(M[i][j]==1){ cnt=0; dfs2(i,j); // cout<<cnt<<endl; if(cnt==0) num[5]++; else if(cnt==1) num[0]++; else if(cnt==2) num[3]++; else if(cnt==3) num[2]++; else if(cnt==4) num[4]++; else if(cnt==5) num[1]++; } } } printf("Case %d: ",++t); for(int i=0;i<6;i++){ if(num[i]>0){ for(int j=0;j<num[i];j++){ printf("%c",res[i]); } } } printf("\n"); } }