拼单词
描述
给你一些单词,请你判断能否把它们首尾串起来串成一串。
前一个单词的结尾应该与下一个单词的道字母相同。
如
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<stdio.h> #include<string.h> #include<stdlib.h> char word[1010][30]; int indegree[30],oudegree[30]; int n,trace[1010],vis[1010],len[1010]; int Euler() { int i,start = -1,end = -1; for(i=0;i<26;i++) { //感觉这里是技巧,我原来写的是将入度等于出度的也计数; //显然这样写更好; if(oudegree[i]!=indegree[i]) { //出度比入度大一,是起点; if(oudegree[i]==indegree[i]+1&&start==-1) start = i; //出度比入度小一,是终点; else if(oudegree[i]+1==indegree[i]&&end==-1) end = i; else return -1; } } //这里的条件必须是同时成立,如果起点和终点只有一个,是不存在欧拉路的 if(start>-1&&end>-1) return start; else if(start==-1&&end==-1)//当图中存在欧拉回路的时候会执行这里 return 0; //因为单词已经排过序,所以返回0,在dfs中就能找到字典序最小的排序 else return -1; } //dfs包含的判断图是否联通图的问题; int dfs(char start,int index) { if(index==n) return 1; int i,begin = 0,end = n - 1,mid; while(begin<=end) { mid = (begin+end)>>1; if(word[mid][0]==start) break; else if(word[mid][0]>start) end = mid - 1; else begin = mid + 1; } if(begin>end) return 0; //这里是当qsort之后 以某个字母开头的单词有多个是,我们要从第一个开始; while(word[mid][0]==start&&mid>=0) mid--; for(i=mid+1;word[i][0]==start;i++) { if(!vis[i]) { trace[index] = i; vis[i] = 1; if(dfs( word[i][len[i]-1],index+1 ) ) return 1; vis[i] = 0; } } return 0; } int cmp(const void *a,const void *b) { return (strcmp((char *)a,(char *)b)); } int main() { int t,i,cont; scanf("%d",&t); while(t--) { scanf("%d",&n); memset(oudegree,0,sizeof(oudegree)); memset(indegree,0,sizeof(indegree)); memset(vis,0,sizeof(vis)); for(i=0;i<n;i++) scanf("%s",word[i]); qsort(word,n,30,cmp); memset(len,0,sizeof(len)); for(i=0;i<n;i++) { len[i] = strlen(word[i]); oudegree[word[i][0]-'a']++; indegree[word[i][len[i]-1]-'a']++; } cont = Euler(); //printf("cont: %d\n",cont); if(cont!=-1&&dfs(cont+'a',0)) { for(i=0;i<n-1;i++) printf("%s.",word[trace[i]]); printf("%s\n",word[trace[n-1]]); } else printf("***\n"); } return 0; }