单词拼接
时间限制: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 ***
View Code#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; struct node { char s[31]; int first,last; }; node a[1001]; int degree_in[1001],degree_out[1001],m,order[1001]; bool used[1001]; int f() { int x1,x2,ans=0,i; x1=x2=0; for(i=0;i<26;++i) { if(abs(degree_in[i]-degree_out[i])>=2) return -1; else if(degree_in[i]-degree_out[i]==1) x1++; else if(degree_in[i]-degree_out[i]==-1) { x2++; ans=i; } } if(x1>1||x2>1) //当时三个度时,必定是 12 和21,相同的不能大于等于2,不然不能构成欧拉回路 return -1; else if(x1==0) { for(i=0;i<26;++i) if(degree_out[i]) return i; //找到一个就行 } else return ans; } bool cmp(node a,node b) { return strcmp(a.s,b.s)<0; } bool dfs(int st,int cnt) { int i; if(cnt==m) return 1; for(i=0;i<m;++i) { if(a[i].first<st||used[i]) continue; else if(a[i].first>st) return false; used[i]=true; order[cnt]=i; if(dfs(a[i].last,cnt+1)) return 1; used[i]=false;//回溯判断是否形成欧拉路径 } return false; } int main() { int N,len,i,start; scanf("%d",&N); while(N--) { memset(used,false,sizeof(used)); memset(degree_out,0,sizeof(degree_out)); memset(degree_in,0,sizeof(degree_in)); scanf("%d",&m); for(i=0;i<m;++i) { scanf("%s",a[i].s); len = strlen(a[i].s); a[i].first =a[i].s[0]-'a'; a[i].last =a[i].s[len-1]-'a'; degree_out[a[i].s[0]-'a']++; degree_in[a[i].s[len-1]-'a']++;//注意这里的入肚出度 } start=f(); if(start ==-1) { printf("***\n"); continue; } sort(a,a+m,cmp); if(!dfs(start,0)) { printf("***\n"); continue; } printf("%s",a[order[0]].s); for(i=1;i<m;i++) printf(".%s",a[order[i]].s); printf("\n"); } return 0; }
这个题目主要是考理解 欧拉回路,注意去除回路就行啦