日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法提高课-搜索-双向广搜 AcWing 190. 字串变换:bfs、双向bfs、queue和unordered_map

發布時間:2025/4/5 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法提高课-搜索-双向广搜 AcWing 190. 字串变换:bfs、双向bfs、queue和unordered_map 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目分析



來源:acwing

分析:

雙向廣搜主要用在最小步數模型(也稱狀態圖模型)里面,這里整個狀態空間一般是指數級別的,用雙向廣搜可以極大地提高運行效率。

雙向廣搜,顧名思義,就是從起點和終點都進行bfs搜索,然后兩者相遇的話,就代表找到了合適的從起點到終點的路徑。下圖展示了起點A和終點B之間能搜到的最小步數的計算過程。

  • 雙向廣搜需要2個哈希表,unordered_map<string, int> da, db; ,分別記錄從起點狀態(狀態:這里是字符串)到中間某狀態的最小步數,從終點狀態到中間某狀態的最小步數。最終的答案就可以通過相加的方式來求。
  • 雙向廣搜同樣需要兩個隊列,q[a]和q[b],來分別進行bfs。當兩個隊列里面同時有值的時候:while(qa.size() && qb.size()),再進行擴展搜索;如果有1個為空,說明從起點到終點是不可達的,也就是無解的。
  • 這里用一個標志位t來記錄 雙向廣搜是否相遇。
  • ac代碼

    #include<bits/stdc++.h> using namespace std; const int N = 6; int n; string a[N],b[N]; // 擴展函數 // 參數:擴展的隊列,到起點的距離,到終點的距離,規則,規則 //返回值:滿足條件的最小步數 int extend(queue<string>& q, unordered_map<string,int>& da, unordered_map<string, int>& db,string a[], string b[]){// 取出隊頭元素string t = q.front();q.pop();for(int i = 0; i < t.size(); i ++) // t從哪里開始擴展for(int j = 0; j < n; j ++) // 枚舉規則//如果t這個字符串的一段= 規則,比如= xyz,才可以替換if(t.substr(i, a[j].size()) == a[j]){// 變換之后的結果state:前面不變的部分+ 變化的部分 + 后面不變的部分// 比如abcd ,根據規則abc--> xu,變成 xud,這里的state就是xudstring state = t.substr(0,i) +b[j] + t.substr(i + a[j].size());// state狀態是否落到b里面去,兩個方向會師,返回最小步數if(db.count(state)) return da[t] + 1 + db[state];// 如果該狀態之前已擴展過,if(da.count(state)) continue;da[state] = da[t] + 1;q.push(state);}return 11;} // 從起點和終點來做bfs int bfs(string A, string B){queue<string> qa, qb; // 兩個方向的隊列//每個狀態到起點的距離da(哈希表),每個狀態到終點的距離db哈希表unordered_map<string, int> da, db; // qa從起點開始搜,qb從終點開始搜qa.push(A), da[A] = 0; // 起點A到起點的距離為0qb.push(B), db[B] = 0; // 終點B到終點B的距離為0// qa和qb都有值,說明可以擴展過來,否則說明是不相交的while(qa.size() && qb.size()){int t; // 記錄最小步數// 哪個方向的隊列的長度更小一些,空間更小一些,從該方向開始擴展,// 時間復雜度比較平滑,否則有1個點會超時if(qa.size() <= qb.size()) t = extend(qa, da, db, a, b);else t = extend(qb, db, da, b, a);// 如果最小步數在10步以內if( t <= 10) return t;}return 11; // 如果不連通或者最小步數>10,則返回大于10的數}int main(){string A, B;cin >> A >> B;// 讀入擴展規則,分別存在a數組和b數組while( cin >> a[n] >> b[n]) n ++;int step = bfs(A,B);if(step > 10) puts("NO ANSWER!");else cout << step << endl; }

    題目來源

    https://www.acwing.com/problem/content/192/

    總結

    以上是生活随笔為你收集整理的算法提高课-搜索-双向广搜 AcWing 190. 字串变换:bfs、双向bfs、queue和unordered_map的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。