8468:单词序列
- 总时间限制:
- 1000ms
- 内存限制:
- 1024kB
- 描述
- 给出两个单词(开始单词和结束单词)以及一个词典。找出从开始单词转换到结束单词,所需要的最短转换序列。转换的规则如下:
1、每次只能改变一个字母
2、转换过程中出现的单词(除开始单词和结束单词)必须存在于词典中
例如:
开始单词为:hit
结束单词为:cog
词典为:[hot,dot,dog,lot,log,mot]
那么一种可能的最短变换是: hit -> hot -> dot -> dog -> cog,
所以返回的结果是序列的长度5;
注意:
1、如果不能找到这种变换,则输出0;
2、词典中所有单词长度一样;
3、所有的单词都由小写字母构成;
4、开始单词和结束单词可以不在词典中。
- 输入
共两行,第一行为开始单词和结束单词(两个单词不同),以空格分开。第二行为若干的单词(各不相同),以空格分隔开来,表示词典。单词长度不超过5,单词个数不超过30。
- 输出
- 输出转换序列的长度。
-
样例输入
hit cog hot dot dog lot log
-
样例输出
-
5
-
题解:
bfs搜索
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<map> using namespace std; const int inf = 233333; int tot = 0; struct ss { string sa; int dis; }s[333]; string b; queue <ss> q; map<string, int> used; int bfs(string a) { q.push((ss){a, 1}); used[a] = 1; while(!q.empty()) { ss u = q.front(); q.pop(); int lenu = u.sa.length(); if(u.sa == b) return u.dis; int ls = 0; for(int j = 0;j < lenu;j ++) { if(u.sa[j] != b[j]) ls++; } if(ls == 1) { return u.dis+1; } for(int i = 1;i <= tot;i ++) { ls = 0; for(int j = 0;j < lenu;j ++) { if(s[i].sa[j] != u.sa[j]) ls++; } if(ls == 1) { if(used[s[i].sa]) continue; s[i].dis = min(u.dis + 1, s[i].dis); q.push(s[i]); used[s[i].sa] = 1; ls = 0; if(s[i].sa == b) return s[i].dis; for(int j = 0;j < lenu;j ++) { if(s[i].sa[j] != b[j]) ls++; } if(ls == 1) { return s[i].dis+1; } } } } return 0; } int main() { for(int i = 1;i <= 300;i ++) { s[i].dis = inf; } string a; cin>>a>>b; if(a.length() != b.length()) { cout<<0; return 0; } int len = a.length(); while(cin>>s[++tot].sa); cout<<bfs(a)<<endl; return 0; }