Catenyms
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 11526 | Accepted: 2993 |
Description
A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For example, the following are catenyms:
A compound catenym is a sequence of three or more words separated by periods such that each adjacent pair of words forms a catenym. For example,
aloha.aloha.arachnid.dog.gopher.rat.tiger
Given a dictionary of lower case words, you are to find a compound catenym that contains each of the words exactly once.
dog.gopher
gopher.rat
rat.tiger
aloha.aloha
arachnid.dog
A compound catenym is a sequence of three or more words separated by periods such that each adjacent pair of words forms a catenym. For example,
aloha.aloha.arachnid.dog.gopher.rat.tiger
Given a dictionary of lower case words, you are to find a compound catenym that contains each of the words exactly once.
Input
The first line of standard input contains t, the number of test cases. Each test case begins with 3 <= n <= 1000 - the number of words in the dictionary. n distinct dictionary words follow; each word is a string of between 1 and 20 lowercase letters on a line by itself.
Output
For each test case, output a line giving the lexicographically least compound catenym that contains each dictionary word exactly once. Output "***" if there is no solution.
Sample Input
2 6 aloha arachnid dog gopher rat tiger 3 oak maple elm
Sample Output
aloha.arachnid.dog.gopher.rat.tiger ***
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <map> #include <queue> #include <vector> #include<functional> #define mod 1000000007 #define inf 0x3f3f3f3f #define pi acos(-1.0) using namespace std; typedef long long ll; const int N=1005; const int M=150005; ll power(ll a,int b,ll c) { ll ans=1; while(b) { if(b%2==1) { ans=(ans*a)%c; b--; } b/=2; a=a*a%c; } return ans; } struct Word { int l; char s[21]; }; struct Edge { int st, ed; bool del; }; Word word[1002]; Edge edge[1002]; int in[30], out[30]; int stk[1002], father[30]; bool mark[30]; int E, top; int cmp ( const void* a, const void* b ) { return strcmp( ((Word*)a)->s, ((Word*)b)->s ); } int find_set ( int x ) { if ( father[x] != x ) father[x] = find_set ( father[x] ); return father[x]; } bool judge () { int t = 0; for ( int i = 0; i < 26; i++ ) if ( mark[i] && father[i] == i ) t++; return t == 1; } void find_path ( int u ) { for ( int i = 0; i < E; i++ ) { if ( ! edge[i].del && edge[i].st == u ) { edge[i].del = true; find_path ( edge[i].ed ); stk[top++] = i; } } } int main() { int cs; scanf("%d",&cs); while ( cs-- ) { scanf("%d",&E); int u, v, c1, c2, start, i; for ( i = 0; i < 26; i++ ) { in[i] = out[i] = 0; father[i] = i; mark[i] = false; } for ( i = 0; i < E; i++ ) { scanf("%s",word[i].s); word[i].l = strlen(word[i].s); } qsort(word, E, sizeof(word[0]), cmp); for ( i = 0; i < E; i++ ) { u = word[i].s[0] - 'a'; v = word[i].s[word[i].l-1] - 'a'; edge[i].st = u; edge[i].ed = v; edge[i].del = false; mark[u] = mark[v] = true; out[u]++; in[v]++; u = find_set ( u ); v = find_set ( v ); if ( u != v ) father[v] = u; } c1 = c2 = 0; start = edge[0].st; for ( i = 0; i < 26; i++ ) { if ( in[i] == out[i] ) continue; else if ( in[i] - 1 == out[i] ) c1++; else if ( out[i] - 1 == in[i] ) { c2++; start = i; } else break; } if ( i == 26 && ((c1 == c2 && c1 == 1) || (c1 == c2 && c1 == 0)) && judge() ) { top = 0; find_path ( start ); for ( i = top - 1; i > 0; i-- ) printf("%s.",word[stk[i]].s); printf("%s ",word[stk[0]].s); } else printf("*** "); } //system("pause"); return 0; }