UVA 11604

来源:互联网 发布:淮阴师范学院网络课程 编辑:程序博客网 时间:2024/04/28 00:36

题意:多组数据,每组给N个字符串(0,1组成),问是否可以构建一个字符串可以由N个字符串用不同方式组成(如可以由S1+S2或S1+S3+S4组成)?


思路:构图,把每个串中的每个字符都看成是一个点,通过字符串两两匹配连边,若其中一个字符串的开头可以连到终点,那么说明存在一种合理方案。


程序如下:


#include<cstdio>
#include<cstring>
using namespace std;

#define N 105
#define L 25

struct Node{
    int v,next;
}e[N*N*L*L];

char s[N][L];
bool ok;
int n,k,Id,E;
int head[N*L],vis[N*L],id[N][L],len[N];

void add(int u,int v) {e[Id].v=v;e[Id].next=head[u];head[u]=Id++;}

void dfs(int u)
{    
    vis[u]=1;
    if (ok) return;
    if (u==E) {ok=true;return;}
    for (int i=head[u];~i;i=e[i].next)
    {
        if (!vis[e[i].v]) dfs(e[i].v);
        if (ok) return;
    }
}

int main()
{
    for (int cas=1;;cas++)
    {
        scanf("%d",&n);
        if (n==0) break;
        memset(head,-1,sizeof(head));
        k=1;Id=1;
        for (int i=1;i<=n;i++)
        {
            scanf("%s%s",s[i]+1,s[i]+1);
            len[i]=strlen(s[i]+1);
            
            for (int j=1;j<=len[i];j++)
                id[i][j]=k++;
        }
        E=k;
        for (int i=1;i<=n;i++)
        {
            for (int h=1;h<=len[i];h++)
            {
                for (int j=1;j<=n;j++)
                {
                    if (i==j&&h==1) continue;
                    
                    for (k=1;k<=len[j]&&h+k-1<=len[i];k++)
                        if (s[i][h+k-1]!=s[j][k]) break;
                        
                    if (h+k-1>len[i]&&k>len[j]) add(id[i][h],E);
                    else if (k>len[j]) add(id[i][h],id[i][k+h-1]);
                    else if (h+k-1>len[i]) add(id[i][h],id[j][k]);
                }
            }
        }
        memset(vis,0,sizeof(vis));
        ok=false;
        for (int i=1;i<=n;i++)
        {
            if (!vis[id[i][1]]) dfs(id[i][1]);
            if (ok) break;
        }
        if (ok) printf("Case #%d: Ambiguous.\n",cas);
        else printf("Case #%d: Not ambiguous.\n",cas);
    }
    return 0;
}

0 0
原创粉丝点击