蒜头君给出两个单词(开始单词和结束单词)以及一个词典。找出从开始单词转换到结束单词,所需要的最短转换序列。转换的规则如下:
1、每次只能改变一个字母
2、转换过程中出现的单词(除开始单词和结束单词)必须存在于词典中
例如:
开始单词为:hit
结束单词为:cog
词典为:[hot,dot,dog,lot,log,mot]
那么一种可能的最短变换是: hit -> hot -> dot -> dog -> cog,
所以返回的结果是序列的长度 55;
注意:
1、如果不能找到这种变换,则输出 00;
2、词典中所有单词长度一样;
3、所有的单词都由小写字母构成;
4、开始单词和结束单词可以不在词典中。
输入格式
共两行,第一行为开始单词和结束单词(两个单词不同),以空格分开。第二行为若干的单词(各不相同),以空格分隔开来,表示词典。单词长度不超过 55, 单词个数不超过 3030。
输出格式
输出转换序列的长度。
输出时每行末尾的多余空格,不影响答案正确性
样例输入复制
hit cog
hot dot dog lot log
样例输出复制
5
本题我刚开始利用DFS,会过部分样例,超时,因为递归层数太多,利用BFS时,数据规模较小,比较适宜,所以可以通过;本题状态是:刚刚访问的的字符串,以及搜索的步数,BFS搜索出来的第一个肯定是步数最少的结果,同时也是最优结果,也就是每次碰倒一个字符串,就和当前字符串比较,是否只有一个字母不同,如果只有一个字不同,表示符合要求,知道和最后一个字符串相比一样符合要求
//@author:hairu,wu
//@from:ahut
#include<iostream>
#include<queue>
#include<cstring>
#include<vector>
#include<memory.h>
using namespace std;
string from,End;
vector<string> v;
int visited[50];
int ans=1000;
//状态结构体
struct point{
string str;
int step;
};
//检查两个字符串是否只有一个相同
int check(string str1,string str2){
int tmp=0;
int len1=str1.length(),len2=str2.length();
if(len1!=len2){
return max(len1,len2);
}
for(int i=0,j=0;i<len1 && j<len2;i++,j++){
if(str1[i]!=str2[j]){
tmp++;
}
}
return tmp;
}
//BFS
void bfs(){
queue<point> q;
point p;
p.str=from;
p.step=0;
q.push(p);
while(!q.empty()){
point newP=q.front();
q.pop();
if(check(newP.str,End)==1){
ans=min(ans,newP.step+2);
break;
}
int size=v.size();
for(int i=0;i<size;i++){
if(!visited[i] && check(v[i],newP.str)==1){
p.str=v[i];
p.step=newP.step+1;
q.push(p);
visited[i]=true;
}
}
}
return ;
}
int main(){
cin >> from >>End;
string str;
cin >> str;
v.push_back(str);
char ch;
while((ch=getchar())!='\n'){
cin >> str;
v.push_back(str);
}
memset(visited,false,sizeof(visited));
bfs();
if(ans==1000){
cout<<0<<endl;
}else{
cout<<ans<<endl;
}
return 0;
}