nyoj--99--单词拼接(欧垃图判定+输出)

单词拼接

时间限制: 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
***
来源
Waterloo local 2003.01.25 /POJ
上传者

张云聪


这道题就是判断是否有欧拉路,然后输出欧垃迹,中间的数据处理有些麻烦,将单词掐头去尾,记录入度出度,因为最多用到26个字母,所以如果一个字母的入度和出度相差2或者更多,就不会有欧垃路,如果入度出度相差为一的字母数超过1,也不会有欧拉路,如果有,那麽就开始dfs,dfs找的时候从一个度数为奇数的点开始,知道全部找完,那么就输出欧垃迹,否则就是不存在


<pre name="code" class="cpp">#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
	char s[30];
	int f,l;
}word[1010];
int in[1010],out[1010],vis[1010],order[1010],m;
int f()
{
	int x1,x2,ans=0;
	x1=x2=0;
	for(int i=0;i<26;i++)
	{
		if(abs(in[i]-out[i])>=2)
		return -1;
		else if(in[i]-out[i]==1)
		x1++;
		else if(in[i]-out[i]==-1)
		{
			x2++;
			ans=i;
		}
	}
	if(x1>1||x2>1)
	return -1;
	else if(x1==0)
	{
		for(int i=0;i<26;i++)
		if(out[i])
		return i;//因为我记录的出度是一个最后一个字母,所以从这儿开始dfs
	}
	else
	return ans;
}
int cmp(node a,node b)
{
	return strcmp(a.s,b.s)<0;
}
bool dfs(int st,int cnt)
{
	if(cnt==m)
	return 1;
	for(int i=0;i<m;i++)
	{
		if(word[i].f<st||vis[i])
		continue;
		else if(word[i].f>st)
		return false;
		vis[i]=1;
		order[cnt]=i;
		if(dfs(word[i].l,cnt+1))
		return 1;
		vis[i]=0;
	}
	return false;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&m);
		memset(vis,0,sizeof(vis));
		memset(in,0,sizeof(in));
		memset(out,0,sizeof(out));
		memset(order,0,sizeof(order));
		for(int i=0;i<m;i++)
		{
			scanf("%s",word[i].s);//单词掐头去尾,记录入度出度 
			int l=strlen(word[i].s);
			word[i].f=word[i].s[0]-'a';
			word[i].l=word[i].s[l-1]-'a';
			in[word[i].l]++;
			out[word[i].f]++;
		}
		int start=f();
		if(start==-1)
		{
			printf("***\n");
			continue;
		}
		sort(word,word+m,cmp);
		if(!dfs(start,0))
		{
			printf("***\n");
			continue;
		}
		printf("%s",word[order[0]].s);
		for(int i=1;i<m;i++)
		printf(".%s",word[order[i]].s);
		printf("\n");
	}
	return 0;
} 


 
     

你可能感兴趣的:(nyoj--99--单词拼接(欧垃图判定+输出))