Catenyms
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10186 | Accepted: 2650 |
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<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<string> 5 #include<algorithm> 6 #include<climits> 7 #define MAXE 1010 8 #define MAXP 28 9 using namespace std; 10 struct Edge 11 { 12 int s,t,next; 13 char str[25]; 14 }edge[MAXE]; 15 int head[MAXE]; 16 int degree[MAXP]; 17 int fa[MAXP]; 18 int stack[MAXE]; 19 bool used[MAXP]; 20 bool sign[MAXE]; 21 bool cur[MAXE][MAXE]; 22 int start; 23 int n; 24 int top; 25 bool cmp(Edge a,Edge b) 26 { 27 return strcmp(a.str,b.str)>0; 28 } 29 void add(int s,int t,int ent) 30 { 31 edge[ent].s=s; 32 edge[ent].t=t; 33 edge[ent].next=head[s]; 34 head[s]=ent; 35 } 36 int find(int x) 37 { 38 int temp=x,i; 39 while(fa[x]!=x) 40 x=fa[x]; 41 while(fa[temp]!=x) 42 { 43 i=fa[temp]; 44 fa[temp]=x; 45 temp=i; 46 } 47 return x; 48 } 49 bool oula() 50 { 51 int temp=0,temp2=0; 52 start=edge[n].s; 53 for(int i=1;i<=26;i++) 54 { 55 if(used[i]) 56 { 57 if(fa[i]==i)temp++; 58 if(degree[i]) 59 { 60 if(degree[i]>1||degree[i]<-1)return false; 61 if(degree[i]==-1)start=i; 62 temp2++; 63 } 64 } 65 } 66 if(temp!=1)return false; 67 if(temp2&&temp2!=2)return false; 68 return true; 69 } 70 void dfs(int s) 71 { 72 for(int i=head[s];i!=-1;i=edge[i].next) 73 { 74 if(!sign[i]) 75 { 76 sign[i]=true; 77 dfs(edge[i].t); 78 stack[++top]=i; 79 } 80 } 81 /*while(1) 82 { 83 if(top==n)break; 84 int temp=head[s]; 85 for(int i=head[s];i!=-1;temp=i=edge[i].next) 86 { 87 if(!sign[i]&&!cur[stack[top]][i])break; 88 } 89 if(temp==-1) 90 { 91 cur[stack[top-1]][stack[top]]=true; 92 sign[stack[top]]=false; 93 sign[stack[top-1]]=false; 94 s=edge[stack[--top]].s; 95 } 96 else 97 { 98 stack[++top]=temp; 99 s=edge[temp].t; 100 sign[temp]=true; 101 } 102 }*/ 103 } 104 int main() 105 { 106 int cas; 107 scanf("%d",&cas); 108 while(cas--) 109 { 110 memset(head,-1,sizeof(head)); 111 memset(sign,false,sizeof(sign)); 112 memset(used,false,sizeof(used)); 113 memset(cur,false,sizeof(cur)); 114 memset(degree,0,sizeof(degree)); 115 scanf("%d",&n); 116 for(int i=1;i<=n;i++) 117 scanf("%s",edge[i].str); 118 sort(edge+1,edge+1+n,cmp); 119 for(int i=1;i<=26;i++) 120 fa[i]=i; 121 for(int i=1;i<=n;i++) 122 { 123 int s=edge[i].str[0]-‘a‘+1,t=edge[i].str[strlen(edge[i].str)-1]-‘a‘+1; 124 add(s,t,i); 125 fa[find(t)]=find(s); 126 degree[s]--; 127 degree[t]++; 128 used[s]=true; 129 used[t]=true; 130 } 131 if(!oula()) 132 { 133 printf("***\n"); 134 } 135 else 136 { 137 top=0; 138 dfs(start); 139 /*for(int i=1;i<=top-1;i++) 140 printf("%s.",edge[stack[i]].str); 141 printf("%s\n",edge[stack[top]].str);*/ 142 for(int i=top;i>=2;i--) 143 printf("%s.",edge[stack[i]].str); 144 printf("%s\n",edge[stack[1]].str); 145 } 146 } 147 return 0; 148 }