单词拼接
时间限制:
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 ***
来源
- Waterloo local 2003.01.25 /POJ 上传者
1.无向图G是欧拉图的充分必要条件是G 是连通图并且没有奇数度顶点。
2.无向图G是半欧拉图的充分必要条件是G是连通的并且恰好有两个奇数度顶点。
3.有向图G是欧拉图的充分必要条件是图是强连通,并且每个定点的入度等于出度。
4.有向图G是半欧拉图的充分必要条件是图单向连通并且恰好有两个奇数度顶点,这两个奇数度顶点一个的出度比入度大1,一个刚好反过来,其余的顶点的出度等于入度。
5.G是非平凡的欧拉图当且仅当G是连通的并且是若干个边不重合的圈的并。
代码如下:
#include <cstdio> #include <cmath> #include <algorithm> #include <cstring> using namespace std; const int maxn = 1010; const int maxm = 30; int in[maxm],out[maxm],route[maxn]; bool vis[maxn]; struct node{ char s[35]; int head,tail; }words[maxn]; int n; bool cmp(node a, node b){return strcmp(a.s,b.s)<0;} void init(){ int len; memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); memset(vis,0,sizeof(vis)); scanf("%d",&n); for (int i=0; i<n; i++){ scanf("%s",words[i].s); len = strlen(words[i].s); words[i].head = words[i].s[0] - 'a'; words[i].tail = words[i].s[len-1] - 'a'; out[words[i].head]++; in[words[i].tail]++; } } int euler(){ int start = -1 , End = -1; for (int 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; if (start == -1 && End == -1) { for (int i=0; i<26; i++) if (out[i]!=0) return i; } return -1; } bool dfs(int x, int cnt){ if (cnt==n) return 1; for (int i=0; i<n; i++){ if (vis[i] || words[i].head<x) continue; else if (words[i].head>x) return 0; else { route[cnt] = i; vis[i] = 1; if (dfs(words[i].tail,cnt+1)) return 1; vis[i] = 0; } } return 0; } int T; int main(){ scanf("%d",&T); while (T--){ init(); int start = euler(); if (start==-1) {printf("***\n"); continue;} sort(words,words+n,cmp); if (dfs(start,0)){ printf("%s",words[route[0]].s); for (int i=1; i<n; i++) printf(".%s",words[route[i]].s); printf("\n"); } else printf("***\n"); } return 0; }
-
第一行是一个整数N(0<N<20),表示测试数据的组数