描述
給出兩個單詞(開始單詞和結束單詞)以及一個詞典。找出從開始單詞轉換到結束單詞,所需要的最短轉換序列。轉換的規則如下:
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
其實這題目,觀察下來數據小,這你進行完美的“枚舉”都可以的,但就是不懂大佬們爲什麼寫的那麼複雜, 一個回溯法解決全部問題,不更加簡單嗎?
#include <iostream>
#include <algorithm>
using namespace std;
string str1,str2,f[35];
bool vis[35],flag=false;
int m=0,len,sum,min1=INT32_MAX;
void bfs(string str,int n){
sum=0;
for (int i = 0; i < len; ++i) {
if(sum>1)
break;
if(str[i]!=str2[i])
sum++;
}
if(sum==1){
flag=true;
min1 = min(min1,n+2);
return;
} else{
for (int i = 0; i < m; ++i) {
sum=0;
if(vis[i]) {
for (int j = 0; j < len; ++j) {
if (sum > 1)
break;
if (str[j] != f[i][j])
sum++;
}
}
if (sum == 1) {
vis[i] = false;
bfs(f[i], n + 1);
vis[i] = true;
}
}
}
return;
}
int main() {
cin>>str1>>str2;
m=0;
while (cin>>f[m]){
vis[m]= true;
m++;
}
len = str1.length();
bfs(str1,0);
if(flag)
cout<<min1;
else
cout<<"0";
return 0;
}