Catenyms
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 7828 | Accepted: 2057 |
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
思路:明显得告诉你了每个单词用一次,也就是经过一次。对于每个单词,从首字母到尾字母连接一条有向边,求出欧拉回路即可;这里要求要用最小字典序来写,那么需要对原字符串排序,怎么排序看你如何建边了,我是邻接表带头指针逆向建边的,所以按从大到小排序;至于有向图的欧拉判定可以百度学习下,对于这题,我没有判断他的连通性。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=30;
const int maxm=1005;
struct node
{
char ch[25];
int l;
} data[maxm];
char output[maxm][25];
int to[maxm],next[maxm],ans[maxm];
int head[maxn],edge,ansi,degree[maxn];
bool vis[maxm],used[maxn];
bool cmp(node a,node b)
{
return strcmp(a.ch,b.ch)>0;
}
inline void add(int u,int v,char a[])
{
strcpy(output[edge],a);
to[edge]=v,next[edge]=head[u],head[u]=edge++;
}
void init()
{
edge=ansi=0;
memset(degree,0,sizeof(degree));
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(used,0,sizeof(used));
}
void dfs(int now)
{
for(int i=head[now]; ~i; i=next[i])
if(!vis[i])
{
vis[i]=1;
dfs(to[i]);
ans[ansi++]=i;
}
}
bool ok(int &u,int &v)
{
u=0,v=0;
bool f=0;
for(int i=1; i<=26; i++)
if(used[i])
{
if(!degree[i]) continue;
f=1;
if(degree[i]==-1)
{
if(u)
{
u=0;
break;
}
u=i;
}
else if(degree[i]==1)
{
if(v)
{
v=0;
break;
}
v=i;
}
else
{
u=0;
break;
}
}
if(!f)
{
for(int i=1; i<=26; i++)
if(used[v=i]) return true;
}
if(u&&v) return true;
else return false;
}
int main()
{
int ca,n,u,v;
scanf("%d",&ca);
while(ca--)
{
scanf("%d",&n);
init();
for(int i=0; i<n; i++)
{
scanf("%s",data[i].ch);
data[i].l=strlen(data[i].ch);
}
sort(data,data+n,cmp);
for(int i=0; i<n; i++)
{
u=data[i].ch[0]-'a'+1;
v=data[i].ch[data[i].l-1]-'a'+1;
degree[u]++,degree[v]--;
add(u,v,data[i].ch);
used[u]=used[v]=1;
}
if(ok(u,v))
{
dfs(v);
if(ansi<n)
{
puts("***");
continue;
}
for(int i=ansi-1; i>=0; i--)
{
if(i==ansi-1) printf("%s",output[ans[i]]);
else printf(".%s",output[ans[i]]);
}
printf("\n");
}
else puts("***");
}
return 0;
}