18.06.02 POJ4128:单词序列 15年期末06
描述
给出两个单词(开始单词和结束单词)以及一个词典。找出从开始单词转换到结束单词,所需要的最短转换序列。转换的规则如下:
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
1 #include <iostream> 2 #include <string.h> 3 #include <algorithm> 4 #include <cstdio> 5 #include <stdlib.h> 6 #include <string> 7 #include <memory> 8 #include <queue> 9 10 using namespace std; 11 12 struct word { 13 char words[7]; 14 int step; 15 word() { step = 0; } 16 }; 17 word diction[31]; 18 word start, endw; 19 int num = 1; 20 bool visited[31]; 21 22 queue<word>all; 23 24 int cmp(word&a, word&b) { 25 int count = 0; 26 int l = strlen(a.words); 27 for (int i = 0; i < l; i++) 28 if (a.words[i] != b.words[i]) 29 count++; 30 return count; 31 } 32 33 void bfs() { 34 bool flag = false; 35 while (!all.empty()) { 36 word now = all.front(); 37 all.pop(); 38 for (int i = 1; i <= num; i++) { 39 if (visited[i] != 1 && cmp(now, diction[i]) == 1) { 40 visited[i] = 1; 41 diction[i].step = now.step + 1; 42 if (cmp(diction[i], endw) == 1) { 43 flag = true; 44 printf("%d\n", diction[i].step + 2); 45 return; 46 } 47 all.push(diction[i]); 48 } 49 } 50 } 51 if (flag == false) 52 printf("0\n"); 53 } 54 55 int main() 56 { 57 cin >> start.words >> endw.words; 58 while (cin >> diction[num].words) 59 num++; 60 if (cmp(start, endw) == 1) 61 { 62 printf("2\n"); 63 return 0; 64 } 65 all.push(start); 66 bfs(); 67 return 0; 68 }
普通的广搜 注意开始单词和结束单词只差一个字母的情况
注定失败的战争,也要拼尽全力去打赢它;
就算输,也要输得足够漂亮。