Catenyms
Time Limit: 1000MS | Memory Limit: 65536K | |
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 ***
————————————————————独立的分割线————————————————————
前言:还是欧拉路,只不过不像是旋转鼓轮那样保证有欧拉路了,这次要先判断。
思路:边权就是该单词,(因此写得很矬),首字母和尾字母就是点。数入度出度、判欧拉,显式栈DFS、输出路径。题目要求字典序,这个好办,先把单词全部读进来,然后存进结构体快排。再建图即可。
代码如下:
/*
ID: j.sure.1
PROG:
LANG: C++
*/
/****************************************/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <map>
#include <string>
#include <climits>
#include <iostream>
#define INF 0x3f3f3f3f
using namespace std;
/****************************************/
const int M = 1e3+5, N = 26;
int tot, head[N], pi, id[N], od[N], m, st;
char path[M][25];
struct Node {
int v, next;
char w[25];
}edge[M];
struct STA {
int u;
char w[25];
}sta[M];
struct Str {
char str[25];
}s[M];
bool vis[N];
int cmp(Str a, Str b)
{
return strcmp(a.str, b.str) >= 0;
}
bool judge()
{
st = -1;
int one = 0;
for(int i = 0; i < 26; i++) if(vis[i]) {
if(st == -1) st = i;
if(abs(od[i]-id[i]) >= 2) return false;
if(abs(od[i]-id[i]) == 1) {
one++;
if(od[i] > id[i]) st = i;
if(one > 2) return false;
}
}
if(one == 1) return false;
return true;
}
void add(int u, int v, char *w)
{
edge[tot].v = v;
strcpy(edge[tot].w, w);
edge[tot].next = head[u];
head[u] = tot++;
}
void Euler()
{
int top = -1;
sta[0].u = st; sta[0].w[0] = '#';
top++;
while(top != -1) {
int u = sta[top].u, i;
char w[25]; strcpy(w, sta[top].w);
for(i = head[u]; i != -1; i = edge[i].next) {
if(edge[i].v != -1) {
int v = edge[i].v;
edge[i].v = -1;
top++;
sta[top].u = v;
strcpy(sta[top].w, edge[i].w);
break;
}
}
if(i == -1) {
if(w[0] != '#') strcpy(path[pi++], w);
top--;
}
}
}
int main()
{
#ifdef J_Sure
// freopen("000.in", "r", stdin);
// freopen(".out", "w", stdout);
#endif
int T;
scanf("%d", &T);
while(T--) {
scanf("%d", &m);
tot = 0;
memset(head, -1, sizeof(head));
memset(id, 0, sizeof(id));
memset(od, 0, sizeof(od));
memset(vis, 0, sizeof(vis));
char w[25];
int u, v;
for(int i = 0; i < m; i++) {
scanf("%s", s[i].str);
}
sort(s, s+m, cmp);
for(int i = 0; i < m; i++) {
int len = strlen(s[i].str);
u = s[i].str[0] - 'a'; v = s[i].str[len-1] - 'a';
vis[u] = vis[v] = 1;
add(u, v, s[i].str);
od[u]++; id[v]++;
}
bool flag = judge();
pi = 0;
if(flag) Euler();
if(pi != m) puts("***");
else {
printf("%s", path[pi-1]);
for(int i = pi-2; i >= 0; i--) {
printf(".%s", path[i]);
}
puts("");
}
}
return 0;
}