這道題原本我用深搜,結果會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所需的最小的轉換次...