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 代码]

posted @ 2011-10-27 15:34  NoRush  阅读(430)  评论(0编辑  收藏  举报