POJ2337 Catenyms
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 11394 | Accepted: 2953 |
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
***
Source
欧拉道路问题。因为要求字典序,所以最好先对字符串排序再dfs。
昨天睡得晚,今天智商下滑。打开编译器,连判是否构成欧拉路都没写,直接排了个序开始暴搜……在被数据卡掉之前已经TLE了。
然后全删了代码开始老老实实写欧拉回路,这回变成了WA,想了想,加了一行代码判欧拉回路起始点,AC。
积累了一个字符串排序的方法:
另开一个数组sk给每个字符串标号,然后对sk数组进行排序,就可以得到字符串的排序。和指针有些像。(然而并不会用指针)
1 #include<cstring> 2 #include<cstdio> 3 #include<cmath> 4 using namespace std; 5 int n; 6 char s[1200][50]; 7 int sk[1200]; 8 int cmp(int a,int b){ 9 if(strcmp(s[a],s[b])==-1)return 0; 10 return 1; 11 } 12 int main(){ 13 int T; 14 scanf("%d",&T); 15 while(T--){ 16 scanf("%d",&n); 17 int i,j; 18 for(i=1;i<=n;i++){ 19 scanf("%s",s[i]); 20 sk[i]=i; 21 } 22 sort(sk+1,sk+n+1,cmp); 23 } 24 return 0; 25 }
然后是正解:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<string> 6 #include<algorithm> 7 using namespace std; 8 const int mxn=1200; 9 int n; 10 int in[mxn],out[mxn]; 11 string s[mxn]; 12 struct edge{ 13 int u,v,next; 14 int id; 15 int vis; 16 }e[mxn*3]; 17 int hd[30],ect=0; 18 int ans[mxn]; 19 int cnt=0; 20 void add_edge(int u,int v,int id){ 21 e[++ect].u=u;e[ect].v=v;e[ect].id=id; 22 e[ect].next=hd[u];e[ect].vis=0;hd[u]=ect; 23 } 24 void dfs(int u){ 25 for(int i=hd[u];i;i=e[i].next){ 26 if(!e[i].vis){ 27 e[i].vis=1; 28 dfs(e[i].v); 29 ans[++cnt]=e[i].id; 30 } 31 } 32 return; 33 } 34 int main(){ 35 int T; 36 scanf("%d",&T); 37 while(T--){ 38 memset(in,0,sizeof in); 39 memset(out,0,sizeof out); 40 memset(hd,0,sizeof hd); 41 scanf("%d",&n); 42 int i,j; 43 ect=0; 44 for(i=1;i<=n;i++)cin>>s[i]; 45 sort(s+1,s+n+1); 46 for(i=n;i;i--){ 47 int u=s[i][0]-'a'; 48 int v=s[i][s[i].length()-1]-'a'; 49 in[v]++; 50 out[u]++; 51 add_edge(u,v,i); 52 } 53 int st=0,ed=0; 54 bool flag=0; 55 for(i=0;i<26;i++){ 56 if(out[i]!=in[i]){//出度不等于入度时判定 57 if(out[i]==in[i]+1){ 58 if(!st)st=i; 59 else flag=1; 60 } 61 else if(in[i]==out[i]+1){ 62 if(!ed)ed=i; 63 else flag=1; 64 } 65 else flag=1; 66 } 67 } 68 if(!st)for(i=0;i<26;i++) 69 if(out[i]){ 70 st=i; 71 break; 72 } 73 if(flag){ 74 printf("***\n"); 75 continue; 76 } 77 cnt=0; 78 dfs(st); 79 if(cnt!=n){ 80 printf("***\n"); 81 continue; 82 } 83 for(i=n;i>1;i--){ 84 cout<<s[ans[i]]; 85 printf("."); 86 } 87 cout<<s[ans[1]]<<endl; 88 } 89 return 0; 90 }
本文为博主原创文章,转载请注明出处。