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:
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 }

 

转载于:https://www.cnblogs.com/SilverNebula/p/5678755.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值