洛谷 P1032 字串变换

来源:互联网 发布:鹿鼎记 知乎 编辑:程序博客网 时间:2024/06/06 09:53

洛谷 P1032 字串变换


题目

题目描述

已知有两个字串 A, B 及一组字串变换的规则(至多6个规则):

     A1 -> B1

     A2 -> B2

规则的含义为:在 A$中的子串 A1 可以变换为 B1、A2 可以变换为 B2 …。

例如:A=’abcd’B=’xyz’

变换规则为:

‘abc’->‘xu’‘ud’->‘y’‘y’->‘yz’

则此时,A 可以经过一系列的变换变为 B,其变换的过程为:

‘abcd’->‘xud’->‘xy’->‘xyz’

共进行了三次变换,使得 A 变换为B。

输入输出格式

输入格式:
键盘输人文件名。文件格式如下:

A B A1 B1 \

   A2 B2 |-> 变换规则

… … /

所有字符串长度的上限为 20。

输出格式:
输出至屏幕。格式如下:

若在 10 步(包含 10步)以内能将 A 变换为 B ,则输出最少的变换步数;否则输出”NO ANSWER!”

输入输出样例

输入样例#1:

abcd xyzabc xuud yy yz

输出样例#1:

3

题解

双向BFS


代码(Pascal)

var a:array[0..1,0..10005]of string;    q:array[0..1,0..100005]of string;    tt:array[0..1,0..10005]of longint;    head,tail:array[0..1]of longint;    bs,t,s1,s2,s:string;    n:longint; procedure rec(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);rec(s);    bs:=s1;t:=s2;n:=0;    while not eof do     begin       readln(s);       if s='' then exit;       inc(n);       rec(s);       a[0,n]:=s1;a[1,n]:=s2;      end;   end; function vis(s:string;t:longint):boolean;  var i:longint;   begin    vis:=false;    for i:=1 to tail[t] do     if q[t,i]=s then exit(true);   end; procedure check(t:longint);  var i:longint;   begin     for i:=1 to tail[1-t] do      if q[1-t,i]=q[t,tail[t]] then       begin         writeln(tt[1-t,i]+tt[t,tail[t]]);         halt;        end;    end; procedure bfs(t:longint);  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;                tt[t,tail[t]]:=tt[t,head[t]]+1;               end;             check(t);            end;          end;       end;    end; procedure main;  begin    head[0]:=0;tail[0]:=1;    head[1]:=0;tail[1]:=1;    q[0,1]:=bs;tt[0,1]:=0;    q[1,1]:=t;tt[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; procedure print;  begin    writeln('NO ANSWER!');   end; begin   init;   main;   print;  end.