• 5793. 【NOIP2008模拟】小S练跑步


    Description

           小S是一个爱锻炼的孩子,他在放假期间坚持在A公园练习跑步。
          但不久后,他就开始为在重复的地点练习感到厌烦了,他就打算去B公园跑步。
          但是小S由于没有去过B公园,他不知道B公园是否适合练习跑步,又不知道在B公园怎样跑是最优的。所以小S就去B公园进行了一番勘测。
          小S在进行了一番勘测后,画出了一张地图,地图每一个位置上都辨识了小S到达该位置后不能往哪一个方位移动。其中有5种表示的符号:“U”代表不能向上移动,“D”代表不能向下移动,“L”代表不能向左移动,“R”代表不能向右移动,如果该位置有障碍物,小S到达那里后无法继续训练,就用“S”来代表。整个公园共有n行m列,小S会从第1行第1列出发,到第n行第m列结束他的练习。
          现在小S想要知道,从起点(即第1行第1列)到终点(第n行第m列),途中最少要改变几次方向(即上一次移动的方向和这一次移动的方向不一样)?
          注意:小S如在训练途中离开公园(即地图范围),则算是结束训练。
     

    Input

          第1行两个整数n和m,它们的定义请看【题目描述】。
          第2~n+1行,每行有m个字符,表示小S的移动方向。
     

    Output

          如果小S从第1行第1列出发无论如何都到达不了第n行第m列,输出“No Solution”,否则输出小S途中最少要改变方向的次数。
     
    Solutions

       裸的广搜。

    代码

      1 const
      2   dx:array [1..4] of longint=(-1,1,0,0);
      3   dy:array [1..4] of longint=(0,0,-1,1);
      4 var
      5   n,m:longint;
      6   a:array [0..501,0..501] of longint;
      7   d:array [0..501,0..501,0..4] of longint;
      8   list:array [0..3000001,1..4] of longint;
      9 procedure init;
     10 var
     11   i,j:longint;
     12   c:char;
     13 begin
     14   readln(n,m);
     15   for i:=1 to n do
     16     begin
     17       for j:=1 to m do
     18         begin
     19           read(c);
     20           if c='U' then a[i,j]:=1;
     21           if c='D' then a[i,j]:=2;
     22           if c='L' then a[i,j]:=3;
     23           if c='R' then a[i,j]:=4;
     24           if c='S' then a[i,j]:=5;
     25         end;
     26       readln;
     27     end;
     28 end;
     29 
     30 function min(o,p:longint):longint;
     31 begin
     32   if o<p then exit(o);
     33   exit(p);
     34 end;
     35 
     36 function fd(x,y,w,tot:longint):boolean;
     37 begin
     38   if (a[x,y]=5) and ((x<>n) or (y<>m)) then exit(false);
     39   if (x>n) or (x<1) then exit(false);
     40   if (y>m) or (y<1) then exit(false);
     41   if tot>=d[x,y,w] then exit(false);
     42   if tot>=d[x,y,0]+1 then exit(false);
     43   d[x,y,0]:=min(d[x,y,0],tot);
     44   d[x,y,w]:=tot;
     45   exit(true);
     46 end;
     47 
     48 procedure bfs;
     49 var
     50   i,j,k,head,tail,x,y,z,w,xx,yy,ww:longint;
     51 begin
     52   head:=0; tail:=0;
     53   for i:=0 to 501 do
     54     for j:=0 to 501 do
     55       for k:=0 to 4 do
     56         d[i,j,k]:=maxlongint div 2;
     57   d[1,1,1]:=0; d[1,1,2]:=0;
     58   d[1,1,3]:=0; d[1,1,4]:=0;
     59   for i:=1 to 4 do
     60     if a[1,1]<>i then
     61       begin
     62         inc(tail);
     63            list[tail,1]:=1; list[tail,2]:=1;
     64            list[tail,3]:=i;
     65       end;
     66   while head<tail do
     67     begin
     68       inc(head);
     69       x:=list[head,1]; y:=list[head,2];
     70       z:=list[head,3]; w:=list[head,4];
     71       for i:=1 to 4 do
     72         if a[x,y]<>i then
     73           begin
     74             xx:=x+dx[i]; yy:=y+dy[i]; ww:=w;
     75         if z<>i then inc(ww);
     76         if not fd(xx,yy,i,ww) then continue;
     77             inc(tail);
     78            list[tail,1]:=xx; list[tail,2]:=yy;
     79         list[tail,3]:=i; list[tail,4]:=ww;
     80           end;
     81     end;
     82 end;
     83 
     84 procedure print;
     85 var
     86   ans,i:longint;
     87 begin
     88   ans:=d[0,0,0];
     89   for i:=1 to 4 do
     90     ans:=min(ans,d[n,m,i]);
     91   if ans<>d[0,0,0] then writeln(ans)
     92                    else writeln('No Solution');
     93 end;
     94 
     95 begin
     96   assign(input,'run.in');
     97   assign(output,'run.out');
     98   reset(input);
     99   rewrite(output);
    100   init;
    101   bfs;
    102   print;
    103   close(input);
    104   close(output);
    105 end.
  • 相关阅读:
    day3
    day2
    day1-存储
    day5-iptables
    MySQL之补充
    11.18
    11.17
    junit基础学习之-测试controller层(2)
    junit基础学习之-简介(1)
    外键和级联
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9457099.html
Copyright © 2020-2023  润新知