Catenyms

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;

}

 

转载于:https://www.cnblogs.com/ffhuguang/p/3342993.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值