题意:给出一张图,它是由一系列字母框按一定顺序从下到上摆放,因此上面的字母框会覆盖一部分下面的字母框,确保每个字母框的四条边都至少会出现一个点,要求输出所有可行的摆放顺序,字典序从小到大输出。

首先可以根据每个字母出现的位置确定每个字母的四条边,然后根据露出来的字母可以确定哪个字母在其他字母上面,所以就可以建出拓扑序的图,由于要输出所有解,所以需要 dfs 来解决,至于字典序只要按照 dfs 的遍历顺序从字母小的到字母大的就行了。

 1 #include<stdio.h>
 2 #include<string.h>
 3 
 4 char s[35][35];
 5 int l[26],r[26],u[26],d[26];
 6 int ma[26][26],id[26],n,vis[26],v[26];
 7 char ans[50];
 8 
 9 void get(int i,int j,int k){
10     if(s[i][j]!='A'+k){
11         int c=s[i][j]-'A';
12         if(!ma[k][c]){
13             ma[k][c]=1;
14             id[c]++;
15         }
16     }
17 }
18 
19 void dfs(int ss,int t){
20     ans[t]=ss+'A';
21     v[ss]=1;
22     if(t==n){
23         for(int i=1;i<=n;++i)printf("%c",ans[i]);
24         printf("\n");
25         v[ss]=0;
26         return;
27     }
28     int que[28],cnt=0;
29     for(int i=0;i<26;++i){
30         if(ma[ss][i])id[i]--;
31         if(vis[i]&&!id[i]&&!v[i])que[++cnt]=i;
32     }
33     for(int i=1;i<=cnt;++i)dfs(que[i],t+1);
34     for(int i=0;i<26;++i)if(ma[ss][i])id[i]++;
35     v[ss]=0;
36 }
37 
38 int main(){
39     int h,w;
40     while(scanf("%d%d",&h,&w)!=EOF){
41         n=0;
42         memset(ma,0,sizeof(ma));
43         for(int i=0;i<26;++i){
44             l[i]=u[i]=35;
45             r[i]=d[i]=0;
46             id[i]=vis[i]=v[i]=0;
47         }
48         for(int i=1;i<=h;++i)scanf("%s",s[i]+1);
49         for(int i=1;i<=h;++i){
50             for(int j=1;j<=w;++j){
51                 if(s[i][j]!='.'){
52                     int c=s[i][j]-'A';
53                     if(!vis[c]){
54                         vis[c]=1;
55                         n++;
56                     }
57                     if(i<u[c])u[c]=i;
58                     if(i>d[c])d[c]=i;
59                     if(j<l[c])l[c]=j;
60                     if(j>r[c])r[c]=j;
61                 }
62             }
63         }
64         for(int k=0;k<26;++k){
65             if(l[k]==35)continue;
66             int i,j;
67             i=u[k];
68             for(j=l[k];j<=r[k];++j)get(i,j,k);
69             i=d[k];
70             for(j=l[k];j<=r[k];++j)get(i,j,k);
71             j=l[k];
72             for(i=u[k]+1;i<d[k];++i)get(i,j,k);
73             j=r[k];
74             for(i=u[k]+1;i<d[k];++i)get(i,j,k);
75         }
76         for(int i=0;i<26;++i){
77             if(vis[i]&&!id[i])dfs(i,1);
78         }
79     }
80     return 0;
81 }
View Code