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
*** 思路:
可以将每个单词看作是两点一边,就变成判断欧拉路径(回路)了,从连通性和出度入度两方面判断,然后打印欧拉路径即可,代码如下(注释
int in[], out[], ans[], start, fa[], n, k;

struct edge {
int u, v, vis;
string s;
bool operator<(const edge &a) const {
return s<a.s;
}
} Edge[]; void init() {
memset(in, , sizeof(in)), memset(out, , sizeof(out));
memset(ans, , sizeof(ans));
k = ;
for(int i = ; i <= ; ++i)
fa[i] = i;
} // Find-Union
int Find(int u) {
if(fa[u] != u)
return fa[u] = Find(fa[u]);
return fa[u];
} void Union(int x, int y) {
x = Find(x), y = Find(y);
if(x != y) fa[x] = y;
} // judge whether connected bool Connect() {
int now = Find(start);
for(int i = ; i <= ; ++i)
if(in[i] || out[i])
if(Find(i) != now)
return false;
return true;
} // judge the in and out and set the start bool check() {
int t1 = , t2 = , i;
for(i = ; i <= ; ++i) {
if(in[i] == out[i]) continue;
else if(in[i] == out[i] + )
t1++;
else if(in[i] == out[i] - ) {
t2++;
start = i;
}
else
break;
}
if(i == && t1 == t2 && (t1 == || t1 == )) {
return true;
}
return false;
} //print the euler path
void dfs(int v) {
for(int i = ; i <= n; ++i) {
if(Edge[i].vis == && Edge[i].u == v) {
Edge[i].vis = ;
dfs(Edge[i].v);
ans[k++] = i;
}
}
} int main() {
ios::sync_with_stdio(false);
int T;
cin >> T;
while(T--) {
cin >> n;
init();
for(int i = ; i <= n; ++i) {
int u, v;
cin >> Edge[i].s;
u = Edge[i].s[] - 'a' + ;
v = Edge[i].s[Edge[i].s.size()-] - 'a' + ;
in[v]++, out[u]++;
Edge[i].u = u, Edge[i].v = v, Edge[i].vis = ;
Union(u, v);
}
sort(Edge+, Edge++n);
start = Edge[].u;
if(check() && Connect()) {
dfs(start);
for(int i = n-; i >= ; --i)
cout << Edge[ans[i]].s << ".";
cout << Edge[ans[]].s << "\n";
} else {
cout <<"***\n";
}
}
return ;
}
 

Day 4 -E - Catenyms POJ - 2337的更多相关文章

  1. Catenyms POJ - 2337(单词+字典序输出路径)

    题意: 就是给出几个单词 看能否组成欧拉回路或路径  当然还是让输出组成的最小字典序的路 解析: 还是把首尾字母看成点   把单词看成边 记录边就好了 这题让我对fleury输出最小字典序又加深了一些 ...

  2. POJ 2337 Catenyms

    http://poj.org/problem?id=2337 题意: 判断给出的单词能否首尾相连,输出字典序最小的欧拉路径. 思路: 因为要按字典序大小输出路径,所以先将字符串排序,这样加边的时候就会 ...

  3. POJ 2337 Catenyms(欧拉回(通)路:路径输出+最小字典序)

    题目链接:http://poj.org/problem?id=2337 题目大意:给你n个字符串,只有字符串首和尾相同才能连接起来.请你以最小字典序输出连接好的单词. 解题思路:跟POJ1386一个意 ...

  4. poj 2337 Catenyms 【欧拉路径】

    题目链接:http://poj.org/problem?id=2337 题意:给定一些单词,假设一个单词的尾字母与还有一个的首字母同样则能够连接.问能否够每一个单词用一次,将全部单词连接,能够则输出字 ...

  5. POJ 2337 Catenyms (有向图欧拉路径,求字典序最小的解)

    Catenyms Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8756   Accepted: 2306 Descript ...

  6. POJ 2337 Catenyms (欧拉回路)

    Catenyms Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8173   Accepted: 2149 Descript ...

  7. POJ 2337 Catenyms(有向图的欧拉通路)

    题意:给n个字符串(3<=n<=1000),当字符串str[i]的尾字符与str[j]的首字符一样时,可用dot连接.判断用所有字符串一次且仅一次,连接成一串.若可以,输出答案的最小字典序 ...

  8. POJ 2337 Catenyms(有向欧拉图:输出欧拉路径)

    题目链接>>>>>> 题目大意: 给出一些字符串,问能否将这些字符串  按照 词语接龙,首尾相接  的规则 使得每个字符串出现一次 如果可以 按字典序输出这个字符串 ...

  9. POJ 2337 Catenyms (欧拉图)

    本文链接http://i.cnblogs.com/EditPosts.aspx?postid=5402042 题意: 给你N个单词,让你把这些单词排成一个序列,使得每个单词的第一个字母和上一个字单词的 ...

随机推荐

  1. Assign the task-HDU3974 dfs序+线段树

    题意: 一个公司有n个员工,每个员工都有一个上司,一个人下属的下属也是这个人的下属,因此可将他们的关系看成一棵树, 然后给定两种操作,C操作是查询当前员工的工作,T操作是将y工作分配给x员工,当一个人 ...

  2. 匈牙利命名法、Camel命名法与Pascal命名法

    Camel命名法:即骆驼式命名法,首字母小写,采用该命名法的名称看起来就像骆驼的驼峰一样高低起伏.Camel命名法有两种形式: 1.混合使用大小写字母,例如runFast 2.单词之间加下划线,例如r ...

  3. Java基础 -4

    IF分支结构 在程序开发的过程中 一共会存在有三组程序逻辑:顺序结构.分支结构.循环结构 if分支结构主要是针对关系表达式进行判断处理的分支操作. if判断 public static void ma ...

  4. jdk动态代理和cglib动态代理底层实现原理超详细解析(jdk动态代理篇)

    代理模式是一种很常见的模式,本文主要分析jdk动态代理的过程 1.举例 public class ProxyFactory implements InvocationHandler { private ...

  5. display:flex下子元素宽度无效

    在子元素上设置: width:60px; flex-shrink:0;

  6. 一、Servlet之14道面试题

    1.什么是Servlet    Servlet是用Java编写的服务端程序,它与协议和平台无关,运行于支持Java的应用服务器中,Java Servlet可以动态的扩展服务器的能力,并采用请求-响应模 ...

  7. 使用input选择本地图片,并且实现预览功能

    1.使用input标签选择本地图片文件 用一个盒子来存放预览的图片 2.JS实现预览 首先添加一个input change事件,再用到 URL.createObjectURL() 方法 用来创建 UR ...

  8. 「CF1C Ancient Berland Circus」

    CF第一场比赛的最后一题居然是计算几何. 这道题的考点也是比较多,所以来写一篇题解. 前置芝士 平面直角坐标系中两点距离公式:\(l=\sqrt{(X_1-X_2)^2+(Y_1-Y_2)^2}\) ...

  9. container-coding-codec

    1 数字容器格式 container format 1.1 一些音频专有的容器: 1.2 静态图像专用的容器: 1.3 视频容器,可以容纳多种类型的音频和视频以及其他媒体 1.4 视频容器格式概述 1 ...

  10. English-Number

    English-Number 1. 基数与序数 2. 数量级前缀 3. 与数量级前缀连用的常用单位 4. 数量的完整写法式例 5. 数学符号 6. 其他常用单位 7. 数字的用法 7.1 日期时间 7 ...