zoukankan      html  css  js  c++  java
  • 广搜练习(一)

    1、  迷宫问题(maze.pas/.in/.out
    【问题描述】

    0 1 1 1 0 1 1 1

    1 0 1 0 1 0 1 0

    0 1 0 0 1 1 1 1

    0 1 1 1 0 0 1 1

    1 0 0 1 1 0 0 0

    0 1 1 0 0 1 1 0

    如上所示的迷宫图,其中1表示不通,0表示通,处于迷宫中的每个位置都可以有 8个方向探索可行路径前进,假设入口设在最左上角,出口位置设在最右下角,编写一个程序,找出一条从入口到出口的最短路径。注意,由于搜索方案可能不唯一,我们假设搜索的顺序优先从所在点的右侧开始搜索,然后搜索右下方,然后是正下方,依次搜索到该点的右上方,这样可以确保输出方案和测试数据一致。

    输入格式

    第一行两个整数m和n,表示行和列(n<=10)

    第二行开始,每行n个0或1共m行,0表示通,1表示不通。

    输出格式

    输出一条最短的路径

    输入样例

    6 8

    0 1 1 1 0 1 1 1

    1 0 1 0 1 0 1 0

    0 1 0 0 1 1 1 1

    0 1 1 1 0 0 1 1

    1 0 0 1 1 0 0 0

    0 1 1 0 0 1 1 0

    输出样例

    (1,1)-->(2,2)-->(3,3)-->(3,4)-->(4,5)-->(4,6)-->(5,7)-->(6,8)

     1 const maxn=10;
     2       maxm=10;
     3       dx:array[1..8] of -1..1=(0,1,1,1,0,-1,-1,-1);
     4       dy:array[1..8] of -1..1=(1,1,0,-1,-1,-1,0,1);
     5 type
     6   data=record
     7          x,y,pre:integer;
     8        end;
     9 var
    10   m,n,i,j,head,tail,x,y,k:integer;
    11   map:array[0..maxm+1,0..maxn+1] of 0..1;
    12   a:array[1..maxm*maxn] of data;
    13 procedure print(k:integer);
    14   begin
    15     if k=1 then begin write('(',a[1].x,',',a[1].y,')');exit;end;
    16     print(a[k].pre);
    17     write('-->(',a[k].x,',',a[k].y,')');
    18   end;
    19 
    20 begin
    21   readln(m,n);
    22   for i:=0 to m+1 do begin map[i,0]:=1;map[i,n+1]:=1;end;
    23   for i:=1 to n do begin map[0,i]:=1;map[m+1,i]:=1;end;
    24   for i:=1 to m do
    25     for j:=1 to n do
    26       read(map[i,j]);
    27   a[1].x:=1; a[1].y:=1;
    28   a[1].pre:=0;
    29   head:=0;tail:=1;
    30   repeat
    31     inc(head);
    32     for i:=1 to 8 do begin
    33       if map[a[head].x+dx[i],a[head].y+dy[i]]=0 then
    34         begin
    35           inc(tail);
    36           a[tail].x:=a[head].x+dx[i];
    37           a[tail].y:=a[head].y+dy[i];
    38           a[tail].pre:=head;
    39           map[a[head].x+dx[i],a[head].y+dy[i]]:=1;
    40           if (a[head].x+dx[i]=m) and (a[head].y+dy[i]=n) then begin print(tail);writeln;halt;end;
    41         end;   
    42     end;
    43   until head>=tail;
    44 end.
    参考程序

    2.奇怪的电梯

    AYYZOJ p1768

    COGS p364

    这题提交了五次才过。。

      1 program p1768;
      2 var
      3  n,a,b,i,ans,head,tail:longint;
      4  k:array[1..200] of longint;
      5  s,x:array[1..200,1..2] of longint;
      6  f:boolean;
      7  pd:set of 1..200;
      8   procedure out(d:longint);
      9   begin
     10    //write(x[d,1]);
     11    repeat
     12     d:=x[d,2];
     13     inc(ans);//write('--',x[d,1]);
     14    until x[d,2]=0;
     15   end;
     16  procedure bfs(a1,b1:longint);
     17  begin
     18   head:=0; tail:=1; x[1,1]:=a; x[1,2]:=0; pd:=[a];
     19   repeat
     20    inc(head);
     21    for i:=1 to 2 do
     22     if (x[head,1]+s[x[head,1],i]>0)and(x[head,1]+s[x[head,1],i]<=n)
     23         and(not(x[head,1]+s[x[head,1],i] in pd)) then
     24      begin
     25       inc(tail);
     26       x[tail,1]:=x[head,1]+s[x[head,1],i];
     27       x[tail,2]:=head;
     28       pd:=pd+[ x[head,1]+s[x[head,1],i] ];
     29       //inc(ans);
     30       if x[tail,1]=b then begin f:=true; out(tail); exit;  {writeln(ans); exit;} end;
     31      end;
     32   until(head>=tail);
     33  end;
     34 begin
     35  readln(n,a,b);
     36  if a=b then begin writeln(0); halt; end;
     37  for i:=1 to n do
     38  begin
     39   read(k[i]);
     40   s[i,1]:=k[i];
     41   s[i,2]:=-k[i];
     42  end;
     43  ans:=0; f:=false;
     44  bfs(a,b);
     45  if not(f) then writeln(-1)
     46  else writeln(ans);
     47 end.//100!
     48 
     49 -------------------------------
     50 program p1768;
     51 var
     52  n,a,b,i,ans,head,tail:longint;
     53  k:array[1..200] of longint;
     54  s,x:array[1..200,1..2] of longint;
     55  f:boolean;
     56  pd:set of 1..200;
     57   procedure out(d:longint);
     58   begin
     59    //write(x[d,1]);
     60    repeat
     61     d:=x[d,2];
     62     inc(ans);//write('--',x[d,1]);
     63    until x[d,2]=0;
     64   end;
     65  procedure bfs(a1,b1:longint);
     66  begin
     67   head:=0; tail:=1; x[1,1]:=a; x[1,2]:=0; pd:=[a];
     68   repeat
     69    inc(head);
     70    for i:=1 to 2 do
     71     if (x[head,1]+s[x[head,1],i]>0)and(x[head,1]+s[x[head,1],i]<=n)
     72         and(not(x[head,1]+s[x[head,1],i] in pd)) then
     73      begin
     74       inc(tail);
     75       x[tail,1]:=x[head,1]+s[x[head,1],i];
     76       x[tail,2]:=head;
     77       pd:=pd+[ x[head,1]+s[x[head,1],i] ];
     78       //inc(ans);
     79       if x[tail,1]=b then begin f:=true; out(tail); exit;  {writeln(ans); exit;} end;
     80      end;
     81   until(head>=tail);
     82  end;
     83 begin
     84  readln(n,a,b);
     85  for i:=1 to n do
     86  begin
     87   read(k[i]);
     88   s[i,1]:=k[i];
     89   s[i,2]:=-k[i];
     90  end;
     91  ans:=0; f:=false;
     92  bfs(a,b);
     93  if not(f) then writeln(-1)
     94  else writeln(ans);
     95 end.//90
     96 
     97 --------------------------------
     98 program p1768;
     99 var
    100  n,a,b,i,ans,head,tail:longint;
    101  k:array[1..200] of longint;
    102  s,x:array[1..200,1..2] of longint;
    103  f:boolean;
    104  pd:set of 1..200;
    105   {procedure out(d:longint);
    106   begin
    107    write(x[d,1]);
    108    repeat
    109     d:=x[d,2]; write('--',x[d,1]);
    110    until x[d,2]=0;
    111   end;       }
    112  procedure bfs(a1,b1:longint);
    113  begin
    114   head:=0; tail:=1; x[1,1]:=a; x[1,2]:=0; pd:=[a];
    115   repeat
    116    inc(head);
    117    for i:=1 to 2 do
    118     if (x[head,1]+s[x[head,1],i]>0)and(x[head,1]+s[x[head,1],i]<=n)
    119         and(not(x[head,1]+s[x[head,1],i] in pd)) then
    120      begin
    121       inc(tail);
    122       x[tail,1]:=x[head,1]+s[x[head,1],i];
    123       //x[tail,2]:=head;
    124       pd:=pd+[ x[head,1]+s[x[head,1],i] ];
    125       inc(ans);
    126       if x[tail,1]=b then begin {out(tail); break;} f:=true; writeln(ans); exit; end;
    127      end;
    128   until(head>=tail);
    129  end;
    130 begin
    131  readln(n,a,b);
    132  for i:=1 to n do
    133  begin
    134   read(k[i]);
    135   s[i,1]:=k[i];
    136   s[i,2]:=-k[i];
    137  end;
    138  ans:=0; f:=false;
    139  bfs(a,b);
    140  if not(f) then writeln(-1);
    141 end.//40
    142 
    143 -------------------------
    144 
    145 begin
    146 writeln(-1);
    147 end.
    148 //30 
    149 -----------------------
    150 
    151 program p1768;
    152 var
    153  n,a,b,i,ans,head,tail:longint;
    154  k:array[1..2000] of longint;
    155  s,x:array[1..2000,1..2] of longint;
    156  f:boolean;
    157   {procedure out(d:integer);
    158   begin
    159    write(x[d,1]);
    160    repeat
    161     d:=x[d,2]; write('--',x[d,1]);
    162    until x[d,2]=0;
    163   end;       }
    164  procedure bfs(a1,b1:integer);
    165  begin
    166   head:=0; tail:=1; x[1,1]:=a; x[1,2]:=0;
    167   repeat
    168    inc(head);
    169    for i:=1 to 2 do
    170     if (x[head,1]+s[x[head,1],i]>0)and(x[head,1]+s[x[head,1],i]<=n) then
    171      begin
    172       inc(tail);
    173       x[tail,1]:=x[head,1]+s[x[head,1],i];
    174       x[tail,2]:=head;
    175       inc(ans);
    176       if x[tail,1]=b then begin {out(tail); break;} f:=true; writeln(ans); exit; end;
    177      end;
    178   until(head>=tail);
    179  end;
    180 begin
    181  readln(n,a,b);
    182  for i:=1 to n do
    183  begin
    184   read(k[i]);
    185   s[i,1]:=k[i];
    186   s[i,2]:=-k[i];
    187  end;
    188  ans:=0; f:=false;
    189  bfs(a,b);
    190  if not(f) then writeln(-1);
    191 end.
    192 //10
    我的广搜
     1 const max=200;
     2         d:array[1..2] of integer=(-1,1);
     3 var
     4   q,pre,k:array[1..max] of integer;
     5   value:array[1..max] of boolean;
     6   n,a,b,i,ans:integer;
     7 procedure bfs;
     8   var head,tail,t,j:integer;
     9   begin
    10     head:=0;tail:=1;
    11     q[1]:=a;pre[1]:=0;value[a]:=false;
    12     repeat
    13       inc(head);
    14       for i:=1 to 2 do
    15         begin
    16           t:=q[head]+d[i]*k[q[head]];
    17           if (t>=1) and (t<=n) and value[t] then begin
    18             inc(tail);
    19             q[tail]:=t;
    20             pre[tail]:=head;
    21             value[t]:=false;
    22             if t=b then begin
    23               ans:=0;
    24               j:=tail;
    25               while pre[j]<>0 do begin inc(ans);j:=pre[j];end;
    26             end;
    27           end;
    28         end;
    29     until head>=tail;
    30   end;
    31 begin
    32   readln(n,a,b);
    33   for i:=1 to n do read(k[i]);
    34   fillchar(value,sizeof(value),true);
    35   ans:=maxint;
    36   if a=b then ans:=0 else bfs;
    37   if ans=maxint then ans:=-1;
    38   writeln(ans);
    39 end.
    广搜
     1 const max=200;
     2 var
     3   k:array[1..max] of integer;
     4   value:array[1..max] of boolean;
     5   n,a,b,i,ans:integer;
     6 procedure dfs(s,step:integer);
     7   begin
     8   if s=b then begin  if step<ans then ans:=step;exit;end;
     9   if (step<ans)and(s>=1)and(s<=n) and value[s] then begin
    10     value[s]:=false;
    11     dfs(s+k[s],step+1);
    12     dfs(s-k[s],step+1);
    13     value[s]:=true;
    14   end;
    15 end;
    16 begin
    17   readln(n,a,b);
    18   for i:=1 to n do read(k[i]);
    19   fillchar(value,sizeof(value),true);
    20   ans:=maxint;
    21   dfs(a,0);
    22   if ans=maxint then ans:=-1;
    23   writeln(ans);
    24 end.
    深搜

    3.最少转弯问题

    AYYZOJ p1460

    COGS p1123

    分析:这个题我感觉非常好啊,与COGS 524激光电话类似,有空做一做。

    广搜的框架,注意在扩展时有深搜的思想,朝一个方向扩展到底,参考程序中用了while循环,再回到扩展起点,很棒的想法。这样就可以用双尾指针法来统计步数(转弯次数),双尾指针法见此课件

     1 const dx:array[1..4] of integer=(0,1,0,-1);
     2       dy:array[1..4] of integer=(1,0,-1,0);
     3 var
     4   m,n,i,j,x1,y1,x2,y2,h,t,t2,ans,x,y:integer;
     5   map:array[1..100,1..100] of integer;
     6   xx,yy,pre:array[1..100] of integer;
     7 begin
     8 assign(input,'turn.in');
     9 reset(input);
    10 assign(output,'turn.out');
    11 rewrite(output);
    12   readln(n,m);
    13   for i:=1 to n do begin
    14    for j:=1 to m do
    15     read(map[i,j]);
    16     readln; end;
    17    readln(x1,y1,x2,y2);
    18    h:=0; t:=1; ans:=0; t2:=1;
    19    xx[1]:=x1; yy[1]:=y1;
    20    while h<t do
    21    begin
    22      inc(h);
    23      for i:=1 to 4 do
    24       begin
    25         x:=xx[h]+dx[i];
    26         y:=yy[h]+dy[i];
    27         while (x<=n)and(y<=m)and(x>=1)and(y>=1)and((map[x,y]=0)or(map[x,y]=2)) do
    28         begin
    29           if map[x,y]=0 then
    30           begin
    31             inc(t);
    32             xx[t]:=x; yy[t]:=y;
    33             map[x,y]:=2;
    34             pre[t]:=h;
    35             if (x=x2)and(y=y2) then begin writeln(ans); halt; end;
    36           end;
    37          x:=x+dx[i]; y:=y+dy[i];
    38         end;
    39       end;
    40    if h=t2 then begin inc(ans); t2:=t; end;
    41    end;
    42 end.
    参考程序
  • 相关阅读:
    初学JAVA随记——代码练习(输出半个菱形 for语句嵌套)
    初学JAVA随记——代码练习(体重问题,含switch、if else、三元条件运算符)
    初学JAVA随记——代码练习(二元一次方程)
    初学JAVA——语句的几个要点
    初学JAVA随记——运算符的几个要点2
    初学JAVA——试写if条件代码(自身体重为例)
    初学JAVA——运算符的几个要点
    初学JAVA——栈空间堆空间的理解
    自制刻度尺插件-前端简易实现"腾讯信用"界面
    JavaScript快速查找节点
  • 原文地址:https://www.cnblogs.com/vacation/p/5184159.html
Copyright © 2011-2022 走看看