将一组单词排列在一个列表,使得列表中任何单词的首字母与其前面单词的尾字母相同。输入一个整数num(单词个数),单词数组char **arr,1<=num<=100,2<=各单词长度<=100,且只包含小写字母。
若列表中的单词可按照要求排列,返回1,否则,返回-1。
如:
a,[abcd,defg,ghij,jkl]
输出1
#include <iostream>
#include <vector>
#include <algorithm>
typedef pair<char,char> type;
bool dfs(vector<type> &a, char key)
{
if(a.empty())
{
return true;
}
else
{
int n=a.size();
for(int i=0;i<n;i++)
{
if(a[i].first==key)
{
auto tmp=a[i];
a.erase(a.begin()+i);
auto flag=dfs(a,tmp.second);
a.insert(a.begin()+i,tmp);
if(flag)
{
return true;
}
}
}
return false;
}
}
int main() {
vector<string> a={"abcd","hkl","dk","kj","jh"};
int n=a.size();
vector<type> a_pair;
for(auto t:a)
{
a_pair.push_back(make_pair(t.front(),t.back()));
}
bool flag=false;
for(int i=0;i<n;i++)
{
auto tmp=a_pair[i];
a_pair.erase(a_pair.begin()+i);
flag=dfs(a_pair,tmp.second);
a_pair.insert(a_pair.begin()+i,tmp);
if(flag)
break;
}
if(flag)
cout<<1;
else
cout<<-1;
return 0;
}
先把字符数组转换成一个有向图,然后DFS遍历,找到一条可以遍历所有点且每个点仅遍历一次的路径。现在不方便写代码。稍后来实现一下,看看是否可以。
DFS好像可以,不知道OJ能不能过了。。
#include <iostream>
#include <vector>
#include <algorithm>
typedef pair<char,char> type;
bool dfs(vector<type> &a, char key)
{
if(a.empty())
{
return true;
}
else
{
int n=a.size();
for(int i=0;i<n;i++)
{
if(a[i].first==key)
{
auto tmp=a[i];
a.erase(a.begin()+i);
auto flag=dfs(a,tmp.second);
a.insert(a.begin()+i,tmp);
if(flag)
{
return true;
}
}
else
return false;
}
}
}
int main() {
vector<string> a={"abcd","dgjh","hkl"};
int n=a.size();
vector<type> a_pair;
for(auto t:a)
{
a_pair.push_back(make_pair(t.front(),t.back()));
}
bool flag=false;
for(int i=0;i<n;i++)
{
auto tmp=a_pair[i];
a_pair.erase(a_pair.begin()+i);
flag=dfs(a_pair,tmp.second);
a_pair.insert(a_pair.begin()+i,tmp);
if(flag)
break;
}
if(flag)
cout<<1;
else
cout<<-1;
return 0;
}
@luoyin500: 100个点数据,减枝减的好,应该可以过。
@Shendu.cc: 感觉有点暴力,我始终觉得是否会有巧技。
@luoyin500: 那我们再想想
@luoyin500: (太久没接触图论了)转换成有向图之后,直接判断是否存在欧拉路径就好了,其实也就是上面说的:找到一条可以遍历所有点且每个点仅遍历一次的路径。 而判断欧拉回路是否存在就是十分简单的了,无需DFS,只需要:
有向图顶点u到v的一条欧拉路径的条件,
u的出度(从这个顶点发出的有向边的数量)比入度(指向这个顶点的有向边的数量)多1, v 的出度比入度少1,而其它顶点的出度和入度都相等。
这样就可以解决了。
每个字母建一个点。对于每个单词,从其首字母建一条边到尾字母。
问题转化为判断图的欧拉路径是否存在
看起来是对的?
欧拉回路是正解。
@Shendu.cc: 是否考虑多个环的情况?
@luoyin500:不用考虑多个环,只需要判断是否存在欧拉路径就可以。
@luoyin500: 多个环的图也是分存在欧拉回路或者不存在欧拉回路的情况。欧拉回路和这个图是不是有多个环没有关系。