NOIp2002 T2 字串变换
题目要求最小变换次数,从搜索的角度讲,可以用BFS或者迭代加深。第一次写双向BFS,感觉还算标准的。判重的时候直接暴力O(tail)For循环了,不过依然很快~
Const maxn=10000; maxq=100000; Var a:array[0..1,0..maxn]of string; q:array[0..1,0..maxq]of string; step:array[0..1,0..maxn]of longint; head,tail:array[0..1]of longint; int,aim,s1,s2,s:string; n:longint; Procedure split(s:string); var k:longint; begin k:=pos(' ',s); s1:=copy(s,1,k-1); s2:=copy(s,k+1,length(s)-k); end; Procedure init; begin readln(s); split(s); int:=s1;aim:=s2; n:=0; while not eof do begin readln(s); if s='' then exit; inc(n); split(s); a[0,n]:=s1;a[1,n]:=s2; end; end; Function vis(s:string;t:byte):boolean; var i:longint; begin vis:=false; for i:=1 to tail[t] do if q[t,i]=s then exit(true); end; Procedure print(k:longint); begin writeln(k); halt; end; Procedure check(t:byte); var i:longint; begin for i:=1 to tail[1-t] do if q[1-t,i]=q[t,tail[t]] then print(step[1-t,i]+step[t,tail[t]]); end; Procedure bfs(t:byte); var i,j,k:longint; pre,tmp:string; begin inc(head[t]);pre:=q[t,head[t]]; for i:=1 to n do begin k:=length(a[t,i]); for j:=1 to length(pre)-k+1 do begin if copy(pre,j,k)=a[t,i] then begin tmp:=copy(pre,1,j-1)+a[1-t,i]+copy(pre,j+k,length(pre)-j-k+1); if not vis(tmp,t) then begin inc(tail[t]); q[t,tail[t]]:=tmp; step[t,tail[t]]:=step[t,head[t]]+1; end; check(t); end; end; end; end; Procedure doublebfs; begin head[0]:=0;head[1]:=0;tail[0]:=1;tail[1]:=1; q[0,1]:=int;q[1,1]:=aim;step[0,1]:=0;step[1,1]:=0; while (head[0]<tail[0])and(head[1]<tail[1])do if tail[1]<tail[0] then bfs(1) else bfs(0); end; Begin init; doublebfs; writeln('NO'); End.
[pascal 代码]