Frame Stacking 良好的拓扑排序题 hoj&poj
Frame Stacking 很好的拓扑排序题 hoj&poj
/*题意自己看。 思路是先找出每个字符对应矩形框的的边界,即四个角的值。 然后排个序。 对每个字符对应的矩型框,扫描在矩形框上和该字符不相同的字符,然后在这两个字符之间连一条边, 更新后一个字符的入度,有个需要注意的地方就是对每一个字符的矩形框上的不同字符, 若出现好几次,则只更新一次入度,这个可以用一个bool数组来判重。 然后图统计好之后就开始拓扑排序。 因为要按字典序输出多组解。 所有采用DFS进行拓扑。 这个题编码有难度,思路也不错,是一道值得推荐的拓扑排序。*/ #include <stdio.h> #include <cstring> #include <map> #include <iostream> #include <algorithm> using namespace std; struct MAP { int r,l,u,d; } MAP[26]; char m[31][31]; char letter[26]; bool top[31][31]; int in[31]; map <char,int> mp; char route[31]; int n,mm,t,num; void topsort() { if(t==num) { printf("%s\n",route); return ; } for(int i=1; i<=num; i++) { if(in[i]==0) { in[i]--; route[t++]=letter[i]; for(int j=1; j<=num; j++) { if(top[i][j]) in[j]--; } topsort(); t--; in[i]++; for(int j=1; j<=num; j++) { if(top[i][j]) in[j]++; } } } } int main() { char s[31]; while(scanf("%d%d",&n,&mm)==2) { memset(m,0,sizeof(m)); memset(in,0,sizeof(in)); memset(top,false,sizeof(top)); num=1; mp.clear(); for(int i=0; i<n; i++) { scanf("%s",s); for(int j=0; j<strlen(s); j++) { m[i][j]=s[j]; if(mp[s[j]]==0&&s[j]>='A'&&s[j]<='Z') { letter[num]=s[j]; mp[s[j]]=num; num++; } } } sort(letter+1,letter+num); num--; mp.clear(); for(int i=1; i<=num; i++) mp[letter[i]]=i; for(int k=1; k<=num; k++) { char tmp=letter[k]; MAP[k].l=MAP[k].u=10000; MAP[k].r=MAP[k].d=-1; for(int i=0; i<n; i++) for(int j=0; j<mm; j++) { if(m[i][j]==tmp&&j<MAP[k].l) MAP[k].l=j; if(m[i][j]==tmp&&j>MAP[k].r) MAP[k].r=j; if(m[i][j]==tmp&&i>MAP[k].d) MAP[k].d=i; if(m[i][j]==tmp&&i<MAP[k].u) MAP[k].u=i; } } for(int k=1; k<=num; k++) { for(int i=MAP[k].u; i<=MAP[k].d; i++) { int l=MAP[k].l; char u=m[i][l]; if(u!=letter[k]&&!top[k][mp[u]]) { top[k][mp[u]]=true; in[mp[u]]++; } } for(int i=MAP[k].u; i<=MAP[k].d; i++) { int r=MAP[k].r; char u=m[i][r]; if(u!=letter[k]&&!top[k][mp[u]]) { top[k][mp[u]]=true; in[mp[u]]++; } } for(int i=MAP[k].l+1; i<MAP[k].r; i++) { int r=MAP[k].u; char u=m[r][i]; if(u!=letter[k]&&!top[k][mp[u]]) { top[k][mp[u]]=true; in[mp[u]]++; } } for(int i=MAP[k].l+1; i<MAP[k].r; i++) { int r=MAP[k].d; char u=m[r][i]; if(u!=letter[k]&&!top[k][mp[u]]) { top[k][mp[u]]=true; in[mp[u]]++; } } } t=0; memset(route,0,sizeof(route)); topsort(); } return 0; }