您的位置:首页 > 其它

Catenyms

2013-09-27 16:35 190 查看
Description

A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For example, the following are catenyms:
dog.gopher
gopher.rat
rat.tiger
aloha.aloha
arachnid.dog

A compound catenym is a sequence of three or more words separated by periods such that each adjacent pair of words forms a catenym. For example,
aloha.aloha.arachnid.dog.gopher.rat.tiger
Given a dictionary of lower case words, you are to find a compound catenym that contains each of the words exactly once.
Input

The first line of standard input contains t, the number of test cases. Each test case begins with 3 <= n <= 1000 - the number of words in the dictionary. n distinct dictionary words follow; each word is a string of between 1 and 20 lowercase letters on a line by itself.
Output

For each test case, output a line giving the lexicographically least compound catenym that contains each dictionary word exactly once. Output "***" if there is no solution.
Sample Input

2
6
aloha
arachnid
dog
gopher
rat
tiger
3
oak
maple
elm

Sample Output

aloha.arachnid.dog.gopher.rat.tiger
***
题意:给定一些字符串,如果一个字符串的尾字符是另一个字符串的的首字符,则可以将两个字符串连接起来,如果所有的字符串不能连接起来那么输出***。否则输出连接成一串的字符串,按字典序由小到大输出
题解:求有向图的欧拉路径。根据有向欧拉图=有向联通图+所有的点的入度等于出度,此时为欧拉回路,如果存在一个点的入度比出度大1,一个点的出度比入度大1,其他的点入度等于出度,那么此时为欧拉路径
用并查集判断是否为连通图,前向星建图。判断欧拉路径还是欧拉回路,然后深度优先搜索路径即可


#include<stdio.h>

#include<iostream>

#include<string.h>

#include<algorithm>

#include<math.h>

using namespace std;

struct lmx{

int v;

int next;

char ss[50];

};

lmx lm[1005];

int pre[1005];

int father[30];

int in[30],out[30];

int visit[1005];

int flag[30];

char re[1005][30];

int ori,des,ant;

int cmp(lmx s,lmx t)

{

return strcmp(s.ss,t.ss)>0;

}

void init()//初始化

{

int i;

for(i=0;i<26;i++) father[i]=i;

memset(in,0,sizeof(in));

memset(out,0,sizeof(out));

memset(pre,-1,sizeof(pre));

memset(visit,0,sizeof(visit));

memset(flag,0,sizeof(flag));

memset(re,'\0',sizeof(re));

}

int finder(int x)

{

if(father[x]==x) return x;

else return father[x]=finder(father[x]);

}

void unioner(int x,int y)

{

int s1=finder(x);

int s2=finder(y);

if(s1==s2) return;

else father[s2]=s1;

}

int oula()//判断是欧拉路径还是欧拉回路或者不存在欧拉路径。0代表不存在,1代表存在欧拉回路,2代表存在欧拉路径

{

int i,cnt=0,j,k;

for(i=0;i<26;i++)

{

if(!flag[i]) continue;

int b=abs(in[i]-out[i]);

if(b>1) return 0;

if(out[i]-in[i]>0) ori=i;

if(out[i]-in[i]<0) des=i;

if(in[i]-out[i]) cnt++;

if(cnt>2) return 0;

}

for(i=0;i<26;i++)

{

if(flag[i]) {j=i;break;}

}

int temp=finder(j);

for(k=j+1;k<26;k++)

{

if(!flag[k]) continue;

if(finder(k)!=temp) return 0;

}

if(cnt==0) {ori=j;return 1;}

return 2;

}

void dfs(int x,int d)

{

int i;

for(i=pre[x];i!=-1;i=lm[i].next)

{

if(visit[i]==0)

{

visit[i]=1;

dfs(lm[i].v,i);

}

}

if(d!=-1) strcpy(re[ant++],lm[d].ss);

}

int main()

{

int test,n,i;

scanf("%d",&test);

while(test--)

{

scanf("%d",&n);

for(i=0;i<n;i++) scanf("%s",lm[i].ss);

sort(lm,lm+n,cmp);

init();

for(i=0;i<n;i++)

{

int b=lm[i].ss[strlen(lm[i].ss)-1]-'a';

int a=lm[i].ss[0]-'a';

lm[i].v=b;

lm[i].next=pre[a];

pre[a]=i;

unioner(a,b);

out[a]++;

in[b]++;

flag[a]=1;

flag[b]=1;

}

// for(i=0;i<n;i++) printf("%s\n",lm[i].ss);

ant=0;

int val=oula();

if(val==0) printf("***\n");

else

{

dfs(ori,-1);

printf("%s",re[ant-1]);

for(i=ant-2;i>=0;i--) printf(".%s",re[i]);

printf("\n");

}

}

return 0;

}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: