Wikioi P1099 字串变换

来源:互联网 发布:java支持linux 编辑:程序博客网 时间:2024/06/07 04:44

        呕。。这一题卡了两天才过。。。原来要用到双向宽搜,即从目标状态向前,初始状态向后进行宽搜,出现相同状态即完成搜索。。。这样时间和空间相对单向宽搜都能得到很大的优化。

        附代码:

program P1099;var  StoreA,StoreB:array[1..100000] of string;  Way:array[1..6,1..2] of string;  n,left,right,head,tail:longint;  Aim:string;procedure ScreenInput;//刚开始写了一种比较麻烦的变换方法var                   //后来删掉重写,读入就保留了,这种读入有点繁琐。  c:char;  i,Way_Num:longint;  s:string;begin  n:=0;  read(c);  for i:=1 to 6 do    begin      Way[i,1]:='';      Way[i,2]:='';    end;  StoreA[1]:='';  Aim:='';  while c<>' ' do    begin      StoreA[1]:=StoreA[1]+c;      read(c);    end;  while not(eoln) do    begin      read(c);      Aim:=Aim+c;    end;  readln;  Way_Num:=0;  readln(s);  while s<>'' do    begin      inc(Way_Num);      i:=1;      while s[i]<>' ' do        begin         Way[Way_Num,1]:=Way[Way_Num,1]+s[i];         inc(i);        end;      inc(i);      while i<=length(s) do        begin          Way[Way_Num,2]:=Way[Way_Num,2]+s[i];          inc(i);        end;      readln(s);    end;  StoreB[1]:=Aim;  n:=Way_Num;  left:=1;  right:=1;  head:=1;  tail:=1;//正向和反向搜索的头和尾end;function UnChongfuA(a:string):boolean;//正向搜索的判重var  i:longint;begin  for i:=1 to right do    if a=StoreA[i] then exit(false);  exit(true);end;function UnChongfuB(a:string):boolean;//反向搜索的判重var  i:longint;begin  for i:=1 to tail do    if a=StoreB[i] then exit(false);  exit(true);end;procedure work(k:longint);var  num,now,len,choose,kk:longint;  i,j:byte;  a,b:string;  flag:boolean;begin  if k>5 then    begin      writeln('NO ANSWER!');      halt;    end;//正向和反向搜索都超过了五步,即意味十步之内无法完成变换  now:=right;  for num:=left to right do    begin      len:=length(StoreA[num]);      a:=StoreA[num];      for i:=n downto 1 do        begin          j:=pos(Way[i,1],a);          if pos(Way[i,1],a)<>0 then          while j<=len-length(Way[i,1])+1 do            begin              if copy(a,j,length(Way[i,1]))=Way[i,1] then flag:=true else flag:=false;              if flag then                begin                  b:=copy(a,1,j-1)+Way[i,2]+copy(a,j+length(Way[i,1]),length(a)-j-length(Way[i,1])+1);                  if UnChongfuA(b) then                    begin                      inc(now);                      StoreA[now]:=b;                    end;                  for kk:=head to tail do                    if StoreB[kk]=StoreA[now] then                      begin                        writeln(k+k-1);                        halt;                      end;                  j:=j+length(Way[i,1])-1;                end;              inc(j);            end;        end;    end;//正向搜索  left:=right+1;  right:=now;  now:=tail;  for num:=head to tail do    begin      len:=length(StoreB[num]);      a:=StoreB[num];      for i:=n downto 1 do        begin          j:=pos(Way[i,2],a);          if pos(Way[i,2],a)<>0 then          while j<=len-length(Way[i,2])+1 do            begin              if copy(a,j,length(Way[i,2]))=Way[i,2] then flag:=true else flag:=false;              if flag then                begin                  b:=copy(a,1,j-1)+Way[i,1]+copy(a,j+length(Way[i,2]),length(a)-j-length(Way[i,2])+1);                  if UnChongfuB(b) then                    begin                      inc(now);                      StoreB[now]:=b;                    end;                  for kk:=left to right do                    if StoreA[kk]=StoreB[now] then                      begin                        writeln(k+k);                        halt;                      end;                  j:=j+length(Way[i,2])-1;                end;              inc(j);            end;        end;    end;//反向搜索  head:=tail+1;  tail:=now;  work(k+1);end;begin  ScreenInput;  work(1);end.


原创粉丝点击