您的位置:首页 > 其它

单词拼接 ----- 深搜

2016-04-15 10:23 253 查看




先判断这些单词能不能构成 接龙 , 能的话在排序 , 然后深搜确定接龙 .

题解 : 如果先确定所有单词的首尾字母的个数 , 如果首字母个数等于尾字母个数就不用管了 , 如果发现首字母比尾字母大1那个这个单词就是首位单词 , 末尾单词也是这样确定 , 如果发现有两个首尾的话 那么就不可能接龙成功 , 如果成环的话 从字典序小的 单词里面找一个字母 , 排序 , 开始深搜 ,

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<limits.h>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<sstream>
#include<map>
#include<cctype>
using namespace std;
struct node
{
char s[31];
int first,last;
}a[1001];
int n,degree_in[1001],degree_out[1001],order[1001],visited[1001];
bool cmp(node a,node b)
{
return strcmp(a.s,b.s)<0;
}
int check()
{
int x1,x2,ans=0,i;
x1=x2=0;
for(i=0;i<26;++i)
{
if(abs(degree_in[i]-degree_out[i])>=2)
return -1;
else if(degree_in[i]-degree_out[i]==1)
x1++;
else if(degree_in[i]-degree_out[i]==-1)
{
x2++;
ans=i;
}
}
if(x1>1||x2>1) //当时三个度时,必定是 12 和21,相同的不能大于等于2,不然不能构成欧拉回路
return -1;
else if(x1==0)
{
for(i=0;i<26;++i)
if(degree_out[i])
return i; //找到一个就行
}
else
return ans;
}
bool DFS(int st,int cnt)
{
int i;
if(cnt==n)
return 1;
for(i=0;i<n;++i)
{
if(a[i].first<st||visited[i])
continue;
else if(a[i].first>st)
return false;
visited[i]=true;
order[cnt]=i;
if(DFS(a[i].last,cnt+1))
return 1;
visited[i]=false;//回溯判断是否形成欧拉路径
}
return false;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
for(int i=0;i<1001;i++)
{
degree_in[i]=degree_out[i]=visited[i]=0;    // 比 三个 memset 要快
}
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s",a[i].s);
int len=strlen(a[i].s);
a[i].first=a[i].s[0]-'a';
a[i].last=a[i].s[len-1]-'a';
degree_out[a[i].s[0]-'a']++;
degree_in[a[i].s[len-1]-'a']++;
}
int flag=check();
if(flag==-1)
{
printf("***\n");
continue;
}
sort(a,a+n,cmp);
if(!DFS(flag,0))
{
printf("***\n");
continue;
}
printf("%s",a[order[0]].s);
for(int i=1;i<n;i++)
printf(".%s",a[order[i]].s);
printf("\n");
}
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: