zoukankan      html  css  js  c++  java
  • 洛谷 P1032 字串变换 广搜

    这道题原本我用深搜,结果会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;//两个队列的头指针和尾指针 
     7     int,aim,s1,s2,s:string; 
     8     n:longint; 
     9 Procedure split(s:string);//将目标状态和初始状态记录下来 
    10 var k:longint; 
    11 begin 
    12   k:=pos(' ',s); 
    13   s1:=copy(s,1,k-1); 
    14   s2:=copy(s,k+1,length(s)-k); 
    15 end; 
    16 Procedure init; //读入
    17 begin 
    18   readln(s); 
    19   split(s); 
    20   int:=s1;//初始状态
    21   aim:=s2;//目标状态 
    22   n:=0; 
    23   while not eof do 
    24   begin 
    25     readln(s); 
    26     if s='' then exit; 
    27     inc(n); 
    28     split(s); 
    29     a[0,n]:=s1;//初始的可以转换的状态
    30     a[1,n]:=s2;//由初始状态转换一步得到的目标状态
    31   end; 
    32 end; 
    33 Function vis(s:string;t:byte):boolean; 
    34 var i:longint; 
    35 begin 
    36   vis:=false; 
    37   for i:=1 to tail[t] do//遍历队列
    38   if q[t,i]=s then exit(true);//如果找到目标状态就返回值true 
    39 end; 
    40 Procedure print(k:longint); 
    41 begin 
    42   writeln(k);//(如果合法)输出最少变换步数 
    43   halt; 
    44 end; 
    45 Procedure check(t:byte); 
    46 var i:longint; 
    47 begin 
    48   for i:=1 to tail[1-t] do //遍历队列(当前的状态保存在队列里)
    49   if q[1-t,i]=q[t,tail[t]] then //如果两个广搜碰头了
    50   print(step[1-t,i]+step[t,tail[t]]);//总的步数就是两个广搜步数之和 
    51 end; 
    52 Procedure bfs(t:byte); //广搜(t=0是正着搜,t=1是反着搜)
    53 var 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//遍历变换规则 
    59   begin 
    60     k:=length(a[t,i]); 
    61     for j:=1 to length(pre)-k+1 do//按照变换规则扩展状态 
    62     begin 
    63       if copy(pre,j,k)=a[t,i] then//如果规则符合 
    64       begin 
    65         tmp:=copy(pre,1,j-1)+a[1-t,i]+copy(pre,j+k,length(pre)-j-k+1);//扩展下一个状态 
    66         if not vis(tmp,t) then//如果没有找到目标状态 
    67         begin 
    68           inc(tail[t]); 
    69           q[t,tail[t]]:=tmp; 
    70           step[t,tail[t]]:=step[t,head[t]]+1;//步数++ 
    71         end; 
    72         check(t);//检查是否终止搜索(注意位置,不然就T了)
    73       end; 
    74     end; 
    75   end; 
    76 end; 
    77 Procedure doublebfs;//用数组下标来区分两个队列和两个广搜 
    78 begin 
    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]<tail[0])and(head[1]<tail[1])do 
    88   if tail[1]<tail[0] then 
    89   bfs(1) else bfs(0);//保持两个广搜的同步 
    90 end; 
    91 Begin 
    92   init; 
    93   doublebfs; 
    94   writeln('NO ANSWER!'); 
    95 End.
  • 相关阅读:
    个人日志-6.27
    <软件工程>课程总结
    团队项目--地铁信息查询-UML图初步设计
    7-4 日报
    7-5小组日报 最终版的发布
    7-1 7-3
    软工日报6-30
    软工日报 6-29
    6-28小组会议记录
    6-27小组讨论内容
  • 原文地址:https://www.cnblogs.com/third2333/p/6829212.html
Copyright © 2011-2022 走看看