洛谷 P1032 字串變換(BFS,字串)

2021-09-10 01:34:37 字數 2385 閱讀 9579

這題要注意的點(keng)挺多的…

題目描述

已知有兩個字串a,b及一組字串變換的規則(至多6個規則):

a 1 -> b 1

a 2 -> b 2 ​

規則的含義為:在 a中的子串 a 1可以變換為 b 1,a 2 可以變換為 b 2…。

例如:a=『abcd』 b=』xyz』

變換規則為:

『abc』->『xu』 『ud』->『y』 『y』->『yz』

則此時,a可以經過一系列的變換變為b,其變換的過程為:

『abcd』 -> 『xud』 -> 『xy』 -> 『xyz』

共進行了3次變換,使得a變換為b。

輸入格式:

輸入格式如下:

a ba 1 b 1

a 2 b 2 |-> 變換規則

… … /

所有字串長度的上限為20。

輸出格式:

輸出至螢幕。格式如下:

若在10步(包含10步)以內能將a變換為b,則輸出最少的變換步數;否則輸出"no answer!"

輸入樣例#1:

abcd xyz

abc xu

ud y

y yz

輸出樣例#1:

分析:

①因為是求最少步數,那麼就應當使用bfs而不是dfs,bfs得到的第乙個解就是最優解(即最少步數)。

②為方便記錄最終步數,建立乙個結構體:

struct node

;

每一步變換的注意點!

a.某乙個字串其符合的子串不止乙個!

b.每一步變換只能變化其中乙個子串!(即使有多個相同的符合子串)

c.每一種變換(位置/變換規則不同)都要放進佇列中!

也就是說bfs的每一層需包括所有變換位置/變換規則不同的結果字串。

1)查詢所有可替換位置:

s1.find (s2 , pos ):在s1中從下標pos開始查詢並返回s2第一次出現的位置下標,若找不到則返回string::npos(若忽略pos則預設從0開始查詢)

int t=0;

while

((t = s1.s.

find

(s2,t)

)!= string::npos)

2)得到替換位置後替換:

s1.replace(pos, len, s2):將從下標pos開始的len長度的字串替換為s2

④bfs的剪枝,不然最後乙個測試點會tle

利用集合set儲存已得到的字串,set中已有的則不再進入佇列。

以下**:

#include

#include

#include

#include

using

namespace std;

struct node

;string a, b, a[10]

, b[10]

;//a,b儲存變換規則

int n =

0, ans;

string trans

(string s,

int pos,

int i)

//pos表示變換起始位置,i表示變換規則

intbfs()

; q.

push

(t1)

; s.

insert

(t1.s)

;while

(!q.

empty()

);//記得step+1

if(t2.s == b)

//判斷

return t2.step;

else

if(t2.step >10)

return-1

;if(!s.

count

(t2.s)

)//查重

t++;}

}}return-1

;//不要忘了這個,有可能未超過10步但是沒有可行方案

}int

main()

洛谷p1032 字串變換 (bfs)

題目概述 字串的子串 必須連續與子串行不同 有至多六種變化規則,若在10步 包含10步 以內能將a變換為b,則輸出最少的變換步數 否則輸出 no answer 題目分析 ac include using namespace std mapint mp 從前出現過的字串不能再次出現 廣度搜尋樹,第一次...

BFS 洛谷 P1032 字串變換

年輕人切忌旋入技術細節漩渦,那是無底之洞 zeo 基礎bfs加一堆字串處理細節 逐個比較是否可替換 替換時把字元拆成三段 前 要替換的 後 根據string 特性 前 替換的 後 可得操作完畢後串 步數壓入佇列繼續bfs map 進行判重 坑的不行 寫的想吐 沒感到任何技術提公升 include i...

洛谷P1032 字串變換 bfs

題意 給定乙個原字串和目標字串,以及幾個字串變換的規則。問能否根據這幾個規則在十步之內把原字串變為目標字串。思路 bfs,佇列維護字串和所經過的步驟這樣乙個二元組而不是簡單的字串。每一次取出乙個字串,用所給的規則進行變換得到新的字串。由於字串中可能有多次匹配,所以用vector存每一次匹配的開始位置...