描述
给你一些单词,请你判断能否把它们首尾串起来串成一串。
前一个单词的结尾应该与下一个单词的道字母相同。
如
aloha
dog
arachnid
gopher
tiger
rat
可以拼接成:aloha.arachnid.dog.gopher.rat.tiger
-
输入
-
第一行是一个整数N(0<N<20),表示测试数据的组数
每组测试数据的第一行是一个整数M,表示该组测试数据中有M(2<M<1000)个互不相同的单词,随后的M行,每行是一个长度不超过30的单词,单词全部由小写字母组成。
输出
-
如果存在拼接方案,请输出所有拼接方案中字典序最小的方案。(两个单词之间输出一个英文句号".")
如果不存在拼接方案,则输出
***
样例输入
-
2 6 aloha arachnid dog gopher rat tiger 3 oak maple elm
样例输出
-
aloha.arachnid.dog.gopher.rat.tiger ***
题意:给你一些单词问你这些单词是否可以首尾相连,如果可以则输出相应的顺序。
思路:构建有向图,先判断该图中是否存在欧拉回路或者欧拉通路,如果存在,则dfs满足条件的结果。
AC代码:
#include<iostream> #include<string> #include<algorithm> #include<string.h> #include<cstdio> #define CLR(arr,value) memset(arr,0,sizeof(arr)); #define N 1001 #define M 26 using namespace std; struct node { int s; int e; char s1[31]; bool vis; }; typedef struct node Node; Node map[N]; bool visit[M]; int in[M]; int out[M]; int Father[M]; int Ran[N]; int p[N]; bool flag; int n; void init() { memset(visit,false,sizeof(visit)); CLR(in,0); CLR(out,0); CLR(p,0); CLR(Ran,0); for(int i=0;i<M;++i) Father[i]=i; } bool operator < (node const& x,node const&x1) { return strcmp(x.s1,x1.s1)<0; } int Find(int x) { if(x==Father[x]) return x; else return Father[x]=Find(Father[x]); } void Union(int a,int b) { int x=Find(a); int y=Find(b); if(x!=y) Father[x]=y; } bool is_connect() { int cnt=0; for(int i=0;i<M;++i) if(visit[i]&&Father[i]==i) cnt++; return cnt==1; } bool is_Euler() { int res=0; for(int i=0;i<M;++i) if(visit[i]&&out[i]!=in[i]) p[res++]=out[i]-in[i]; return (res==0||(res==2&&p[0]*p[1]==-1)); } void dfs(int now,int _e,int cur) { if(flag) return; for(int i=0;i!=n;++i) { if(!map[i].vis&&_e==map[i].s) { Ran[cur-1]=now; if(cur+1==n) { flag=true; Ran[cur]=i; return; } map[i].vis=true; dfs(i,map[i].e,cur+1); map[i].vis=false; } } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); init(); for(int i=0;i!=n;++i) { scanf("%s",map[i].s1); map[i].s=map[i].s1[0]-'a'; map[i].e=map[i].s1[strlen(map[i].s1)-1]-'a'; map[i].vis=false; Union(map[i].s,map[i].e); out[map[i].s]++; in[map[i].e]++; visit[map[i].s]=true; visit[map[i].e]=true; } if(is_connect()&&is_Euler()) { std::sort(map,map+n); flag=false; for(int i=0;i!=n;++i) { map[i].vis=true; dfs(i,map[i].e,1); map[i].vis=false; } for(int i=0;i!=n-1;++i) printf("%s.",map[Ran[i]].s1); printf("%s",map[Ran[n-1]].s1); printf("\n"); } else printf("***\n"); }return 0; }