描述
给你一些单词,请你判断能否把它们首尾串起来串成一串。
前一个单词的结尾应该与下一个单词的道字母相同。
如
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
***
-
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; char str[1000][31]; bool used[1000]; int in[26]; int out[26]; int s[1000]; int stack[1000]; int n; int compare(const void*a,const void *b){ char *p1=(char*)a; char *p2=(char*)b; return strcmp(p1,p2); } int Judge(){ int i; int last=-1,first=-1; for(i=0;i<26;++i){ if(in[i]!=out[i]){ if(out[i]-in[i]==1&&first==-1) first=i; else if(out[i]-in[i]==-1&&last==-1) last=i; else return -1; } } if(first>-1&&last>-1) return first; else if(first==-1&&last==-1){ for(i=0;i<26;++i) if(in[i]!=0) return i; } else return -1; } bool DFS(char first,int index){ if(index==n) return true; int i,b,e,m; b=0;e=n-1; while(b<=e){ //二分法查找这个首字符,排序好的 m=(b+e)/2; if(str[m][0]==first) break; else if(str[m][0]>first) e=m-1; else b=m+1; } if(b>e) return false; while(str[m][0]==first&&m>=0) --m; for(i=m+1;str[i][0]==first;++i){ if(!used[i]){ stack[index]=i; used[i]=true; if(DFS(str[i][s[i]-1],index+1)) return true; used[i]=false; } } return false; } int main(){ int t,i,first; scanf("%d",&t); while(t--){ scanf("%d",&n); for(i=0;i<n;i++) scanf("%s",str[i]); memset(used,0,sizeof(used)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); qsort(str,n,31*sizeof(char),compare); for(i=0;i<n;++i){ s[i]=strlen(str[i]); ++out[str[i][0]-'a']; ++in[str[i][s[i]-1]-'a']; } first=Judge(); if(first!=-1&&DFS(first+'a',0)){ for(i=0;i<n-1;++i) printf("%s.",str[stack[i]]); printf("%s\n",str[stack[n-1]]); } else printf("***\n"); } return 0; }