计蒜客-1244-单词序列(BFS)

蒜头君给出两个单词(开始单词和结束单词)以及一个词典。找出从开始单词转换到结束单词,所需要的最短转换序列。转换的规则如下:

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;
}
发布了83 篇原创文章 · 获赞 3 · 访问量 1360

猜你喜欢

转载自blog.csdn.net/weixin_41296877/article/details/105298599