Catenyms
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:
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 ***
1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 #include<stack> 5 #include<cstdlib> 6 #include<algorithm> 7 using namespace std; 8 9 struct str 10 { 11 char word[35]; 12 }; 13 14 struct Edge 15 { 16 int u,v; 17 }; 18 19 str s[1005]; 20 int in[27],out[27]; 21 bool vis[1005]; 22 vector<Edge>edges; 23 vector<int>G[1005]; 24 stack<int>S; 25 int n,beg; 26 bool flag; 27 28 bool cmp(str a,str b) 29 { 30 return strcmp(a.word,b.word)<0; 31 } 32 33 void init() 34 { 35 edges.clear(); 36 while(!S.empty())S.pop(); 37 for(int i=0;i<26;i++)G[i].clear(); 38 memset(in,0,sizeof(in)); 39 memset(out,0,sizeof(out)); 40 memset(vis,0,sizeof(vis)); 41 flag=0; 42 } 43 44 void dfs(int u) 45 { 46 for(int i=0;i<G[u].size();i++) 47 { 48 int x=G[u][i]; 49 if(!vis[x]) 50 { 51 vis[x]=1; 52 dfs(edges[x].v); 53 S.push(x); 54 } 55 } 56 } 57 58 void solve() 59 { 60 int cnt1=0,cnt2=0; 61 for(int i=0;i<26;i++) 62 { 63 if(in[i]==out[i]) 64 continue; 65 else if(out[i]-in[i]==1) 66 { 67 cnt1++; 68 beg=i; 69 if(cnt1>=2) 70 return; 71 } 72 else if(in[i]-out[i]==1) 73 { 74 cnt2++; 75 if(cnt2>=2) 76 return; 77 } 78 else 79 return; 80 } 81 if(cnt1>1||cnt2>1)return; 82 if(cnt1==0) 83 for(int i=0;i<26;i++) 84 if(out[i]) 85 { 86 beg=i; 87 break; 88 } 89 flag=1; 90 } 91 92 int main() 93 { 94 //freopen("in.txt","r",stdin); 95 int T; 96 scanf("%d",&T); 97 while(T--) 98 { 99 init(); 100 scanf("%d",&n); 101 for(int i=0;i<n;i++) 102 scanf("%s",s[i].word); 103 sort(s,s+n,cmp); 104 for(int i=0;i<n;i++) 105 { 106 int u=s[i].word[0]-‘a‘; 107 int v=s[i].word[strlen(s[i].word)-1]-‘a‘; 108 in[v]++; 109 out[u]++; 110 edges.push_back((Edge){u,v}); 111 G[u].push_back(i); 112 } 113 solve(); 114 if(!flag) 115 { 116 printf("***\n"); 117 continue; 118 } 119 dfs(beg); 120 if(S.size()!=n) 121 { 122 printf("***\n"); 123 continue; 124 } 125 else 126 { 127 bool key=0; 128 while(!S.empty()) 129 { 130 int x=S.top(); 131 if(key) 132 printf("."); 133 printf("%s",s[x].word); 134 key=1; 135 S.pop(); 136 } 137 printf("\n"); 138 } 139 } 140 return 0; 141 }