POJ 1128 拓扑排序

题意:

给出一个由字母边框拼起来的图,问这个图是又多少种构造方式,输出所有的方式。

分析:

如果这个字母边框中有其他的字母,则可以看成是一个这个字母到那个字母的一条边。然后用拓扑排序输出就可以了。

#include<cstdio>
#include<cstring>

using namespace std;

int h,w;

char g[35][35];
bool mp[35][35];
bool vis[35];
int ans[35];
bool flag[35];
int q[35],cnt;

void build(){
    int i,j,k,l;
    for(i=1;i<=h;i++){
        for(j=1;j<=w;j++){
            char c=g[i][j];
            if(c=='.') continue;
            if(!flag[c-'A']){
                int c1,c2,r;        //左边界,有边界,下边界。
                flag[c-'A']=1;
                //左边界
                for(k=1;;k++){
                    for(l=i;l<=h;l++){
                        if( g[l][k]==c ){
                            break;
                        }
                    }
                    if( l<=h ) break;
                }
                c1=k;
                //右边界
                for(k=w;;k--){
                    for(l=i;l<=h;l++){
                        if(g[l][k]==c) break;
                    }
                    if(l<=h) break;
                }
                c2=k;
                //下边界
                for(k=h;;k--){
                    for(l=c1;l<=c2;l++){
                        if(g[k][l]==c) break;
                    }
                    if(l<=c2) break;
                }
                r=k;
                //扫描边框
                for(k=c1;k<=c2;k++){
                    int u=c-'A';
                    int v=g[i][k]-'A';
                    if(u!=v){
                        mp[u][v]=1;
                    }
                    v=g[r][k]-'A';
                    if(u!=v) mp[u][v]=1;
                }
                for(k=i;k<=r;k++){
                    int u=c-'A';
                    int v=g[k][c1]-'A';
                    if(u!=v) mp[u][v]=1;
                    v=g[k][c2]-'A';
                    if(u!=v) mp[u][v]=1;
                }
            }
        }
    }
}

void dfs(int i){
    if(i==cnt){
        for(int j=0;j<cnt;j++){
            printf("%c",ans[j]+'A');
        }
        printf("\n");
        return;
    }
    for(int j=0;j<cnt;j++){
        if(vis[q[j]]) continue;
        ans[i]=q[j];
        bool state=true;
        for(int k=i;k>0&&state;k--){
            for(int l=0;l<k;l++){
                if(mp[ans[k]][ans[l]]){
                    state=0;
                    break;
                }
            }
        }
        if(!state) continue;
        vis[q[j]]=1;
        dfs(i+1);
        vis[q[j]]=0;
    }
}

int main(){
    while(~scanf("%d%d",&h,&w)){
        for(int i=1;i<=h;i++){
            scanf("%s",g[i]+1);
        }
        memset(mp,0,sizeof mp);
        memset(flag,0,sizeof flag);
        build();
        cnt=0;
        for(int i=0;i<26;i++){
            if(flag[i]){
                q[cnt++]=i;
                vis[i]=0;
            }
        }
        dfs(0);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40679299/article/details/83590242