这是切的很痛苦的一道题,自己测试了很多样例却终究不过,中间也做了诸多修改,后来无奈去网上看题解,发现遗漏了一种情况,就是两个窗口可能边框都能看见,但是一个嵌套在另一里面,而我判定是不是 “top window”的条件只要是边框全部暴露在外面,所以呢发现边框完整没有遮挡的时候,对边框包围区域遍历一遍看里面有没有字母,这样就能判定一个“top window”了。
主要思路就是沿着右下左上的方向行进,遇到不是相同字母或越界的情况就变化方向,如果提前表示方向的d>3,说明边框被遮挡不完整,若完整的话对框内区域进行查找看有没有其他字母。
1 #include<stdio.h> 2 #include<string.h> 3 #include<ctype.h> 4 #define N 110 5 6 char maze[N][N]; 5 int vis[N][N]; 8 int ans[26]; 9 int dx[]= {0,1,0,-1}; 10 int dy[]= {1,0,-1,0}; 11 int n,m,d; 12 13 int find(int x,int y,int s,int t) 14 { 15 int i,j; 16 for(i=x+1;i<s;i++) 17 for(j=y+1;j<t;j++) 18 if(isalpha(maze[i][j])) 19 return 1; 20 return 0; 21 } 22 23 void dfs(int x,int y,int c) 24 { 25 int nx,ny; 26 nx=x+dx[d]; 27 ny=y+dy[d]; 28 int s=x,t=y,p,q; 29 while(1) 30 { 31 if(nx==s&&ny==t&&d==3&&maze[nx][ny]==c&&vis[nx][ny]&&fa[nx][ny]==nx*m+ny) 32 { 33 if(!find(s,t,p,q)) 34 ans[c-'A']=1; 35 else ans[c-'A']=-1; 36 return; 37 } 38 while(nx<0||nx>=n||ny<0||ny>=m||maze[nx][ny]!=c||vis[nx][ny]) 39 { 40 d++; 41 if(d>3) 42 { 43 ans[c-'A']=-1; 44 return; 45 } 46 if(d==2) 47 p=x,q=y; 48 nx=x+dx[d]; 49 ny=y+dy[d]; 50 } 51 52 vis[x][y]=1; 53 x=nx; 54 y=ny; 55 if(nx==s&&ny==t&&d==3&&maze[nx][ny]==c&&vis[nx][ny]&&fa[nx][ny]==nx*m+ny) 56 { 57 ans[c-'A']=1; 58 return; 59 } 60 nx=x+dx[d]; 61 ny=y+dy[d]; 62 } 63 } 64 65 int main(void) 66 { 67 int i,j,c; 68 while(scanf("%d%d",&n,&m)&&(n||m)) 69 { 70 memset(fa,-1,sizeof(fa)); 71 memset(ans,0,sizeof(ans)); 72 memset(maze,0,sizeof(maze)); 73 memset(vis,0,sizeof(vis)); 74 for(i=0; i<n; i++) 75 scanf("%s",maze[i]); 76 for(i=0; i<n; i++) 77 for(j=0; j<m; j++) 78 { 79 c=maze[i][j]; 80 if(c>='A'&&c<='Z'&&!ans[c-'A']) 81 { 82 fa[i][j]=i*m+j; 83 d=0; 84 dfs(i,j,c); 85 } 86 } 87 for(i=0; i<26; i++) 88 if(ans[i]==1) 89 putchar(i+'A'); 90 puts(""); 91 } 92 return 0; 93 }