Catenyms
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10533 | Accepted: 2754 |
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 ***
给出n个单词,如果两两可以构成catenym则按字典序输出,否则输出***。catenym:前一个单词的最后一个字母与后一个单词的第一
个字母相同。
输入字符串而后排序,字典序大的首现加入进去,而后dfs,最后判断是否连通。
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "string"
using namespace std;
const int MAXN = 1010;
struct node
{
/* data */
int to, next, index;
bool vis;
}e[MAXN];
int in[30], out[30], head[30], ans[MAXN], n, tot, cnt;
string s[MAXN];
void add(int u, int v, int index)
{
e[tot].to = v;
e[tot].next = head[u];
e[tot].index = index;
e[tot].vis = false;
head[u] = tot++;
}
void dfs(int u)
{
for(int i = head[u]; i != -1; i = e[i].next)
if(!e[i].vis) {
e[i].vis = true;
dfs(e[i].to);
ans[cnt++] = e[i].index;
}
}
int main(int argc, char const *argv[])
{
int t;
scanf("%d", &t);
while(t--) {
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(head, -1, sizeof(head));
scanf("%d", &n);
for(int i = 0; i < n; ++i)
cin >> s[i];
sort(s, s + n);
tot = 0, cnt = 0;
int st = 100;
for(int i = n - 1; i >= 0; --i) {
int u = s[i][0] - 'a', v = s[i][s[i].length() - 1] - 'a';
add(u, v, i);
out[u]++, in[v]++;
if(u < st) st = u;
if(v < st) st = v;
}
int cn1 = 0, cn2 = 0;
for(int i = 0; i < 26; ++i) {
if(out[i] - in[i] == 1) {
cn1++;
st = i;
}
else if(out[i] - in[i] == -1) cn2++;
else if(out[i] - in[i] != 0) cn1 = 3;
}
if(!((!cn1 && !cn2) || (cn1 == 1 && cn2 == 1))) {
printf("***\n");
continue;
}
dfs(st);
if(cnt != n) {
printf("***\n");
continue;
}
for(int i = cnt - 1; i >= 0; --i) {
cout << s[ans[i]];
if(i) printf(".");
else printf("\n");
}
}
return 0;
}