单词拼接
时间限制:
3000 ms | 内存限制:
65535 KB
难度:
5
-
描述
-
给你一些单词,请你判断能否把它们首尾串起来串成一串。
前一个单词的结尾应该与下一个单词的道字母相同。
如
aloha
dog
arachnid
gopher
tiger
rat
可以拼接成:aloha.arachnid.dog.gopher.rat.tiger
-
输入
-
第一行是一个整数N(0<N<20),表示测试数据的组数
每组测试数据的第一行是一个整数M,表示该组测试数据中有M(2<M<1000)个互不相同的单词,随后的M行,每行是一个长度不超过30的单词,单词全部由小写字母组成。
输出
-
如果存在拼接方案,请输出所有拼接方案中字典序最小的方案。(两个单词之间输出一个英文句号".")
如果不存在拼接方案,则输出
***
样例输入
-
2 6 aloha arachnid dog gopher rat tiger 3 oak maple elm
样例输出
-
aloha.arachnid.dog.gopher.rat.tiger ***
-
第一行是一个整数N(0<N<20),表示测试数据的组数
欧拉图或半欧拉图都是能成功拼接的。
1.无向连通图G是欧拉图,当且仅当G不含奇数度结点(G的所有结点度数为偶数);
2.无向连通图G含有欧拉通路,当且仅当G有零个或两个奇数度的结点;
3.有向连通图D是欧拉图,当且仅当该图为连通图且D中每个结点的入度=出度
4.有向连通图D含有欧拉通路,当且仅当该图为连通图且D中除两个结点外,其余每个结点的入度=出度,且此两点满足deg-(u)-deg+(v)=±1。(起始点s的入度=出度-1,结束点t的出度=入度-1 或两个点的入度=出度)
5.一个非平凡连通图是欧拉图当且仅当它的每条边属于奇数个环。
6.如果图G是欧拉图且 H = G - uv,则H有奇数个u,v-迹仅在最后访问v;同时,在这一序列的u,v-迹中,不是路径的迹的条数是偶数。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define Maxsize 1010
struct Node{
int to;
}e[30][100];
int indegree[30];
int outdegree[30];
int next[Maxsize];
char str[Maxsize][35];
int que[Maxsize];
bool vis[Maxsize];
int top;
int m;
int count;
int cmp(const void *a,const void *b)
{
return strcmp((char *)a,(char *)b);
}
void init()
{
for(int i=0;i<30;i++)
{e[i][0].to=0;}
memset(indegree,0,sizeof(indegree));
memset(outdegree,0,sizeof(outdegree));
memset(vis,0,sizeof(vis));
count=m;top=0;
}
bool dfs(int u,int c)
{
if(c==count)
return true;
for(int i=1;i<=e[u][0].to;i++)
{
Node &E=e[u][i];
if(!vis[E.to])
{
vis[E.to]=1;
que[top++]=E.to;
if(dfs(next[E.to],c+1))
return true;
top--;
vis[E.to]=0;
}
}
return false;
}
int main()
{
int n;
int i;
scanf("%d",&n);
while(n--)
{
scanf("%d",&m);
int l,r;
init();
for(i=0;i<m;i++)
{
scanf("%s",str[i]);
}
qsort(str,m,sizeof(str[0]),cmp);
for(i=0;i<m;i++)
{
// printf("%s\n",str[i]);
l=str[i][0]-'a';
int t=++e[l][0].to;e[l][t].to=i;
r=strlen(str[i])-1;
next[i]=str[i][r]-'a';
outdegree[l]++;indegree[next[i]]++;
}
int flag=0;
for(i=0;i<26;i++)
if(indegree[i]!=outdegree[i])
flag++;
// printf("%d\n",flag);
if(flag!=2&&flag!=0)
{
printf("***\n");
continue;
}
if(flag==2)
{
for(i=0;i<26;i++)
if(outdegree[i]-1==indegree[i])
{
dfs(i,0);
break;
}
}
else dfs(0,0);
if(top!=m)
{
printf("***\n");
continue;
}
for(i=0;i<top-1;i++)
printf("%s.",str[que[i]]);
printf("%s\n",str[que[top-1]]);
}
return 0;
}