题意:
一些相框叠在一起,A---Z表示每个相框的四条边,给出从上向下看的图
可以重叠,但每个相框保证四条边上至少有一点出现,求叠放次序,多种结果按字母序输出
在书上看到这题 感觉题目蛮有意思的
也没想到是dfs拓扑排序
思路:
确定每个框的四个角,每条边上都有点出现,就可以确定了。
对其他相框遍历边,若出现别的相框,就添加这条边。
这样就构成一个图,就可以用拓扑排序了。
dfs拓扑排序保证多解字母序输出。
要注意的地方:
出现的边入度先赋为0。
一条边只添加一次。
直接构图,不用找到最上面的相框。
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
#define ll __int64
using namespace std;
int q[35][35],in[35],up[35],lft[35],rght[35],down[35],n;
char s[35][35];
void dfs(char* ss,int cnt)
{
if(cnt==n)
{
puts(ss);
return ;
}
int i,j;
for(i=0;i<26;i++)
{
if(in[i]==0)
{
for(j=0;j<26;j++)
if(q[i][j]==1)
in[j]--;
in[i]=-1;
ss[cnt]=i+'A';
dfs(ss,cnt+1);
in[i]=0;
for(j=0;j<26;j++)
if(q[i][j]==1)
in[j]++;
}
}
}
int main()
{
int h,w,i,j,p,l,r,d,u,top,flag;
while(~scanf("%d%d",&h,&w))
{
for(i=0;i<h;i++)
scanf("%s",s[i]);
for(i=0;i<=27;i++)
{
up[i]=inf;
lft[i]=inf;
down[i]=-1;
rght[i]=-1;
}
//统计每个相框的上下左右界
for(i=0;i<h;i++)
{
for(j=0;j<w;j++)
{
if(s[i][j]!='.')
{
p=s[i][j]-'A';
up[p]=min(up[p],i);
down[p]=max(down[p],i);
lft[p]=min(lft[p],j);
rght[p]=max(rght[p],j);
}
}
}
//找到最上的相框//根本不用啊
/*flag=1;
for(i=0;i<26;i++)
{
if(up[i]!=inf)
{
l=lft[i];
u=up[i];
r=rght[i];
d=down[i];
printf("i:%d l:%d u:%d r:%d d:%d\n",i,l,u,r,d);
for(j=l+1;j<=r;j++)
{
if(s[u][j]!=s[u][j-1]||s[d][j]!=s[d][j-1])
{
flag=0;
break;
}
}
if(!flag) continue;
for(j=u+1;j<=d;j++)
{
if(s[j][r]-'A'!=s[j-1][r]||s[j][l]-'A'!=s[j-1][l])
{
flag=0;
break;
}
}
if(flag)
{
puts("findtop");
top=i;
break;
}
}
}
printf("top:%d\n",top);*/
//建图
memset(in,-1,sizeof in);//入度
memset(q,0,sizeof q);//两点间关系
n=0;//出现字母个数
for(i=0;i<=27;i++)
{
if(up[i]!=inf)
{
if(in[i]==-1) in[i]=0;//该点只要出现 入度先定为0 表示它存在了 一直错这里!
n++;
l=lft[i];
u=up[i];
r=rght[i];
d=down[i];
for(j=l;j<=r;j++)
{
if(s[u][j]-'A'!=i)
{
if(q[i][s[u][j]-'A']) continue;
q[i][s[u][j]-'A']=1;
if(in[s[u][j]-'A']!=-1) in[s[u][j]-'A']++;
else in[s[u][j]-'A']=1;
}
if(s[d][j]-'A'!=i)
{
if(q[i][s[d][j]-'A']) continue;
q[i][s[d][j]-'A']=1;
if(in[s[d][j]-'A']!=-1) in[s[d][j]-'A']++;
else in[s[d][j]-'A']=1;
}
}
for(j=u;j<=d;j++)
{
if(s[j][r]-'A'!=i)
{
if(q[i][s[j][r]-'A']) continue;
q[i][s[j][r]-'A']=1;
if(in[s[j][r]-'A']!=-1) in[s[j][r]-'A']++;
else in[s[j][r]-'A']=1;
}
if(s[j][l]-'A'!=i)
{
if(q[i][s[j][l]-'A']) continue;
q[i][s[j][l]-'A']=1;
if(in[s[j][l]-'A']!=-1) in[s[j][l]-'A']++;
else in[s[j][l]-'A']=1;
}
}
}
}
// for(i=0;i<=5;i++)
// printf("%c in:%d\n",i+'A',in[i]);
char ss[30]="";
dfs(ss,0);
}
return 0;
}