百鍊 4128:單詞序列

描述
給出兩個單詞(開始單詞和結束單詞)以及一個詞典。找出從開始單詞轉換到結束單詞,所需要的最短轉換序列。轉換的規則如下:
1、每次只能改變一個字母
2、轉換過程中出現的單詞(除開始單詞和結束單詞)必須存在於詞典中
例如:
開始單詞爲:hit
結束單詞爲:cog
詞典爲:[hot,dot,dog,lot,log,mot]
那麼一種可能的最短變換是: hit -> hot -> dot -> dog -> cog,
所以返回的結果是序列的長度5;
注意:
1、如果不能找到這種變換,則輸出0;
2、詞典中所有單詞長度一樣;
3、所有的單詞都由小寫字母構成;
4、開始單詞和結束單詞可以不在詞典中。

輸入
共兩行,第一行爲開始單詞和結束單詞(兩個單詞不同),以空格分開。第二行爲若干的單詞(各不相同),以空格分隔開來,表示詞典。單詞長度不超過5,單詞個數不超過30。
輸出
輸出轉換序列的長度。

輸入樣例:

  1. hit cog
  2. hot dot dog lot log

輸出樣例:

  1. 加粗樣式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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章