洛谷 P1032 字串變換 廣搜

2022-08-05 04:30:20 字數 3409 閱讀 3112

這道題原本我用深搜,結果會t,wcnm,然後就直接參考抄題解了

1 const maxn=10000

;

2 maxq=100000

; 3 var a:array[0..1,0..maxn]of string;//

變換規則

4 q:array[0..1,0..maxq]of string;//

兩個佇列

5 step:array[0..1,0..maxn]of longint;//

步數6 head,tail:array[0..1]of longint;//

兩個佇列的頭指標和尾指標

7int,aim,s1,s2,s:string; 8

n:longint;

9 procedure split(s:string);//

將目標狀態和初始狀態記錄下來

10var

k:longint;

11begin

12 k:=pos('

',s);

13 s1:=copy(s,1,k-1

); 14 s2:=copy(s,k+1,length(s)-k);

15end;

16 procedure init; //

讀入17

begin

18readln(s);

19split(s);

20int:=s1;//

初始狀態

21 aim:=s2;//

目標狀態

22 n:=0

; 23

while not eof do

24begin

25readln(s);

26if s=''

then exit;

27inc(n);

28split(s);

29 a[0,n]:=s1;//

初始的可以轉換的狀態

30 a[1,n]:=s2;//

由初始狀態轉換一步得到的目標狀態

31end;

32end;

33 function vis(s:string;t:byte

):boolean;

34var

i:longint;

35begin

36 vis:=false

; 37

for i:=1 to tail[t] do

//遍歷佇列

38if q[t,i]=s then exit(true);//

如果找到目標狀態就返回值true

39end;

40procedure print(k:longint);

41begin

42 writeln(k);//

(如果合法)輸出最少變換步數

43halt;

44end;

45 procedure check(t:byte

); 46

vari:longint;

47begin

48for i:=1 to tail[1-t] do

//遍歷佇列(當前的狀態儲存在佇列裡)

49if q[1-t,i]=q[t,tail[t]] then //

如果兩個廣搜碰頭了

50 print(step[1-t,i]+step[t,tail[t]]);//

總的步數就是兩個廣搜步數之和

51end;

52 procedure bfs(t:byte); //

廣搜(t=0是正著搜,t=1是反著搜)

53var

i,j,k:longint;

54 pre,tmp:string

; 55

begin

56 inc(head[t]);//

頭指標加一

57 pre:=q[t,head[t]];//

入隊 58

for i:=1 to n do

//遍歷變換規則

59begin

60 k:=length(a[t,i]);

61for j:=1 to length(pre)-k+1

do//

按照變換規則擴充套件狀態

62begin

63if copy(pre,j,k)=a[t,i] then//

如果規則符合

64begin

65 tmp:=copy(pre,1,j-1)+a[1-t,i]+copy(pre,j+k,length(pre)-j-k+1);//

擴充套件下乙個狀態

66if not vis(tmp,t) then//

如果沒有找到目標狀態

67begin

68inc(tail[t]);

69 q[t,tail[t]]:=tmp;

70 step[t,tail[t]]:=step[t,head[t]]+1;//

步數++

71end;

72 check(t);//

檢查是否終止搜尋(注意位置,不然就t了)

73end;

74end;

75end;

76end;

77 procedure doublebfs;//

用陣列下標來區分兩個佇列和兩個廣搜

78begin

79 head[0]:=0;//

第乙個佇列的頭指標

80 head[1]:=0;//

第二個佇列的頭指標

81 tail[0]:=1;//

第乙個佇列的尾指標

82 tail[1]:=1;//

第二個佇列的尾指標

83 q[0,1]:=int;//

初始狀態

84 q[1,1]:=aim;//

目標狀態

85 step[0,1]:=0;//

步數86 step[1,1]:=0;//

步數 87

while (head[0]0])and(head[1]1])do

88if tail[1]0

] then

89 bfs(1) else bfs(0);//

保持兩個廣搜的同步

90end;

91begin

92init;

93doublebfs;

94 writeln('

no answer!

');

95 end.

洛谷 P1032 字串變換

洛谷 p1032 字串變換 題目描述 已知有兩個字串 a,b 及一組字串變換的規則 至多6個規則 a1 b1 a2 b2 規則的含義為 在 a 中的子串 a1 可以變換為 b1 a2 可以變換為 b2 例如 a abcd b xyz 變換規則為 abc xu ud y y yz 則此時,a 可以經過...

洛谷 P1032 字串變換

已知有兩個字串 a,b 及一組字串變換的規則 至多 6 個規則 a1 b1 a2 b2 規則的含義為 在a 中的子串 a1 可以變換為 b1 a2可以變換為 b2 例如 a abcd bb xyz 變換規則為 abc xu ud y y yz 則此時,a 可以經過一系列的變換變為 b 其變換的過程為...

洛谷P1032字串變換

題目描述 已知有兩個字串a,b a,b 及一組字串變換的規則 至多6個規則 a1 b1 a 1 b1 a2 b2 a 2 b2 規則的含義為 在a的子串中a1 a 1可以變成b1 b 1,a2 a 2可以變成b2 b 2 求a a 變成b role presentation b b所需的最小的轉換次...