单词拼接
时间限制:
3000 ms | 内存限制:
65535 KB
难度:
5
-
描述
-
给你一些单词,请你判断能否把它们首尾串起来串成一串。
前一个单词的结尾应该与下一个单词的道字母相同。
如
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 ***
-
欧拉图+深度优先搜索!
-
刚接触图论,毕竟水平有限,参照了网上的代码!
-
AC码:
-
#include<stdio.h> #include<string.h> #include<stdlib.h> char str[1006][35]; int out[30],in[30],visit[1006],len[1006]; int n,stack[1006]; int Euler() { int i,start=-1,end=-1; for(i=0;i<26;i++) { if(out[i]!=in[i]) { if(out[i]-in[i]==1&&start==-1) start=i; else if(out[i]-in[i]==-1&&end==-1) end=i; else return -1; } } if(start>-1&&end>-1) return start; else if(start==-1&&end==-1) { for(i=0;i<26;i++) { if(out[i]!=0) return i; } } else return -1; } 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)/2; if(str[mid][0]==start) break; else if(str[mid][0]>start) end=mid-1; else begin=mid+1; } if(begin>end) return 0; while(str[mid][0]==start&&mid>=0) --mid; for(i=mid+1;str[i][0]==start;i++) { if(!visit[i]) { stack[index]=i; visit[i]=1; if(DFS(str[i][len[i]-1],index+1)) return 1; visit[i]=0; } } return 0; } int cmp(const void *a,const void *b) { return (strcmp((char *)a,(char *)b)); } int main() { int T,i,count; scanf("%d",&T); while(T--) { scanf("%d",&n); memset(out,0,sizeof(out)); memset(in,0,sizeof(in)); memset(visit,0,sizeof(visit)); for(i=0;i<n;i++) { scanf("%s",str[i]); } // 单词首字母按从小到大的顺序排列 qsort(str,n,sizeof(str[0]),cmp); for(i=0;i<n;i++) { len[i]=strlen(str[i]); out[str[i][0]-'a']++; in[str[i][len[i]-1]-'a']++; } // 欧拉图判断 count=Euler(); if(count!=-1&&DFS(count+'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; }
-
第一行是一个整数N(0<N<20),表示测试数据的组数