首页 > 代码库 > 【bfs】【中等难度】tyvj P1234 - bench与奔驰

【bfs】【中等难度】tyvj P1234 - bench与奔驰

P1234 - bench与奔驰

From zhangbh001    Normal (OI) 总时限:10s    内存限制:128MB    代码长度

限制:64KB

P1234 - bench与奔驰

背景 Background

公园里有个人在练开奔驰 - -!,但是总是撞在bench上 (众人曰:狼来了,快跑啊!)

描述 Description

公园里的bench与奔驰都是无敌的,不会被撞坏。
由于开奔驰的人比较"有特点",总是向上下左右四个方向开,而且只会在撞到椅子之后改变方向(起步时除外) - -!
现在他给你一张地图,上面标明 他的位置 、 公园里的bench的位置 和 他想到达的位置,可能会有冲出地图的可能
请你告诉他最少撞多少下才能到达目的地,并答应事成之后会给你一辆奔驰..............................................的照片

输入格式 InputFormat

第一行,两个数,分别表示地图的行和列,都不大于50
以下是地图,"."表示地面,"S"表示起点,"E"表示终点,"B"表示bench(什么意思呢?)
保证只有一个终点和一个起点,并不会出现其他字符

输出格式 OutputFormat

第一行,表示他能不能到达目的地。如果能,就输出"Yes"。否则,输出"No"
如果能到达目的地,就在第二行输出最少的撞击次数

样例输入 SampleInput 

测试数据1:
5 5
BBBBB
B...B
BSE.B
B...B
BBBBB

测试数据2:
3 3
S..
...
..E

样例输出 SampleOutput 

测试数据1:
Yes
0

测试数据2:
No

数据范围和注释 Hint

测试数据1:点火后直接向右走
测试数据2:四个方向都会冲出地图

来源 Source

某个经典的游戏......

思路 thinkings

痛苦的bfs。。。我讨厌bfs。。。真TM难写

核心:对于当前位置,先判断下一个位置会不会冲出去,冲出去就没什么好做的了,
        如果不会冲出去再判断是不是椅子

bfs的时候要传4个量:x,y(坐标),direction(方向),hit(撞击次数)

注意:1.由于范围很小,不需要像某些题解说的一次走一条直线,一步步慢慢挪也可以过(而且好像 也是0ms)

        2.转向时候不能直接跨出去一步,应该是原地转向,然后入队直行,因为你不知道跨出去这一步是椅子还是出界,如果判断更麻烦

        3.刚开始的时候需要将4个方向都入队

        4.血的教训(见下)

教训

        x和y判断是否出界就是cin>>M>>N;x对应M,y对应N;

        不要自作聪明调过来啊!!会死人啊!!

代码

#include<iostream>#include<cstdlib>#include<cstdio>#include<algorithm>#include<cmath>#include<map>#include<ctime>#include<cstring>#define ll long long#define inf 0x7fffffffstruct note{    int x,y,dire,hitting;    };int N,M;note queue[2550];int i,j,k,p,q,l,r,s,t,startx,starty,head,tail,left,right,use,tmp,sum,ans;const int movex[4]={-1,0,1,0};const int movey[12]={0,1,0,-1};char board[75][75];bool b[75][75][5]={0};bool flag;using namespace std;inline int read(){    int x=0;char ch=getchar();    while(ch>9||ch<0)ch=getchar();    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}    return x;}void readin(){    cin>>M>>N;    for (i=1;i<=M;i++)    {        for (j=1;j<=N;j++)        {            cin>>board[i][j];            if (board[i][j]==S) {startx=i;starty=j;}        }    }}//------------------------------------------------------------void bfs(){    while (head<=tail)    {        int xx,yy,direction,hit;        xx=queue[head].x;yy=queue[head].y;direction=queue[head].dire;hit=queue[head].hitting; head++;        if (board[xx][yy]==E) {ans=hit; flag=true; return;}        if ( (xx+movex[direction]>0)&&(xx+movex[direction]<=M)&&(yy+movey[direction]>0)&&(yy+movey[direction]<=N) )         {                         if ( (board[xx+movex[direction]][yy+movey[direction]]==B) )               {                                int dir;                dir=( (direction+1+4)%4 );                if ( (b[xx][yy][dir]==0)&&(xx<=M)&&(yy<=N)&&(xx>0)&&(yy>0) )                    {                                                tail++;                         queue[tail].x=xx;queue[tail].y=yy;queue[tail].dire=dir;queue[tail].hitting=hit+1;                         b[xx][yy][dir]=1;                  }                dir=( (direction-1+4)%4 );                if ( (b[xx][yy][dir]==0)&&(xx<=M)&&(yy<=N)&&(xx>0)&&(yy>0) )                    {                        tail++;                         queue[tail].x=xx;queue[tail].y=yy;queue[tail].dire=dir;queue[tail].hitting=hit+1;                         b[xx][yy][dir]=1;                  }                }            else              {                xx=xx+movex[direction];yy=yy+movey[direction];                if ( (b[xx][yy][direction]==0)&&(xx<=M)&&(yy<=N)&&(xx>0)&&(yy>0) )                   {                        tail++;                         queue[tail].x=xx;queue[tail].y=yy;queue[tail].dire=direction;queue[tail].hitting=hit;                         b[xx][yy][direction]=1;                  }            }         }     }}//------------------------------------------------------------int main(){    flag=false;    readin();    head=1;tail=4;    queue[1].x=startx;queue[1].y=starty;queue[1].dire=0;queue[1].hitting=0; b[startx][starty][0]=1;    queue[2].x=startx;queue[2].y=starty;queue[2].dire=1;queue[2].hitting=0; b[startx][starty][1]=1;    queue[3].x=startx;queue[3].y=starty;queue[3].dire=2;queue[3].hitting=0; b[startx][starty][2]=1;    queue[4].x=startx;queue[4].y=starty;queue[4].dire=3;queue[4].hitting=0; b[startx][starty][3]=1;    bfs();    if (flag==true) { cout<<"Yes"<<endl; cout<<ans<<endl; }               else { cout<<"No"<<endl; }}
去注释代码
#include<iostream>#include<cstdlib>#include<cstdio>#include<algorithm>#include<cmath>#include<map>#include<ctime>#include<cstring>#define ll long long#define inf 0x7fffffffstruct note{    int x,y,dire,hitting;    };int N,M;note queue[2550];int i,j,k,p,q,l,r,s,t,startx,starty,head,tail,left,right,use,tmp,sum,ans;const int movex[4]={-1,0,1,0};const int movey[12]={0,1,0,-1};char board[75][75];bool b[75][75][5]={0};bool flag;using namespace std;//       0//    3     1//       2inline int read(){    int x=0;char ch=getchar();    while(ch>9||ch<0)ch=getchar();    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}    return x;}void readin(){    cin>>M>>N;    for (i=1;i<=M;i++)    {        for (j=1;j<=N;j++)        {            cin>>board[i][j];            if (board[i][j]==S) {startx=i;starty=j;}        }    }}//------------------------------------------------------------void bfs(){    /* 对于当前位置,先判断下一个位置会不会冲出去,冲出去就没什么好做的了,       如果不会冲出去再判断是不是椅子*/     while (head<=tail)    {        int xx,yy,direction,hit;        xx=queue[head].x;yy=queue[head].y;direction=queue[head].dire;hit=queue[head].hitting; head++;        if (board[xx][yy]==E) {ans=hit; flag=true; /*cout<<"到啦 喂 停车哇!!"<<endl;*/return;}        /*Pending!cout<<"Pending:"<<queue[head-1].x<<‘ ‘<<queue[head-1].y<<‘ ‘<<queue[head-1].dire<<‘ ‘<<queue[head-1].hitting;*/        if ( (xx+movex[direction]>0)&&(xx+movex[direction]<=M)&&(yy+movey[direction]>0)&&(yy+movey[direction]<=N) ) //不会冲出去        {             /*Pending!cout<<"不会冲出去  "; */            if ( (board[xx+movex[direction]][yy+movey[direction]]==B) )   //按着这个方向运行下去会撞车的情况             {                /*Pending!cout<<"会撞车  "; */                int dir;                dir=( (direction+1+4)%4 );                if ( (b[xx][yy][dir]==0)&&(xx<=M)&&(yy<=N)&&(xx>0)&&(yy>0) )                    {                        /*Pending!cout<<"右拐  "; */                        tail++;                         queue[tail].x=xx;queue[tail].y=yy;queue[tail].dire=dir;queue[tail].hitting=hit+1;                         b[xx][yy][dir]=1;                  }                dir=( (direction-1+4)%4 );                if ( (b[xx][yy][dir]==0)&&(xx<=M)&&(yy<=N)&&(xx>0)&&(yy>0) )                    {                        /*Pending!cout<<"左拐  "; */                        tail++;                         queue[tail].x=xx;queue[tail].y=yy;queue[tail].dire=dir;queue[tail].hitting=hit+1;                         b[xx][yy][dir]=1;                  }                }            else  //可以继续运行的情况             {                /*Pending!cout<<"不会撞车  "; */                xx=xx+movex[direction];yy=yy+movey[direction];                if ( (b[xx][yy][direction]==0)&&(xx<=M)&&(yy<=N)&&(xx>0)&&(yy>0) )                   {                        tail++;                         queue[tail].x=xx;queue[tail].y=yy;queue[tail].dire=direction;queue[tail].hitting=hit;                         b[xx][yy][direction]=1;                  }            }         }         /*else Pending!cout<<"会冲出去  ";         cout<<endl;*/    }}//------------------------------------------------------------int main(){    flag=false;    readin();    head=1;tail=4;    queue[1].x=startx;queue[1].y=starty;queue[1].dire=0;queue[1].hitting=0; b[startx][starty][0]=1;    queue[2].x=startx;queue[2].y=starty;queue[2].dire=1;queue[2].hitting=0; b[startx][starty][1]=1;    queue[3].x=startx;queue[3].y=starty;queue[3].dire=2;queue[3].hitting=0; b[startx][starty][2]=1;    queue[4].x=startx;queue[4].y=starty;queue[4].dire=3;queue[4].hitting=0; b[startx][starty][3]=1;    //for (i=1;i<=tail;i++)    //cout<<queue[i].x<<‘ ‘<<queue[i].y<<‘ ‘<<queue[i].dire<<‘ ‘<<queue[i].hitting<<endl;    //system("pause");    bfs();    if (flag==true) { cout<<"Yes"<<endl; cout<<ans<<endl; }               else { cout<<"No"<<endl; }    //for (i=1;i<=tail;i++)    //cout<<queue[i].x<<‘ ‘<<queue[i].y<<‘ ‘<<queue[i].dire<<‘ ‘<<queue[i].hitting<<endl;}
原汁原味没去注释和调试语句的代码
const xi:array[1..4] of shortint=(1,-1,0,0);      yi:array[1..4] of shortint=(0,0,1,-1);var d,i,j,m,n,x1,x2,y1,y2,k,ans:longint;    a:array[0..51,0..51] of char;    f:array[1..51,1..51,1..4] of longint;    b:array[1..51,1..51,1..4] of boolean;procedure dfs(h,x,y,d:longint);var i,j,l,k,xx,yy:longint;begin  //readln;  x:=x+xi[d];y:=y+yi[d];  if (x>m) or (x=0) or (y>n) or (y=0) then exit;  {for i:=1 to m do   begin    for j:=1 to n do     write(f[i,j]:3);    writeln;   end;             }  if (a[x,y]<>B) then  begin    if (y=y2) and (x=x2) then begin if h<ans then ans:=h; exit; end;    if (h>=f[x,y,d]) and not(b[x,y,d])then exit;    if h<f[x,y,d] then f[x,y,d]:=h;    b[x,y,d]:=false;    while (a[x+xi[d],y+yi[d]]<>B) and (x+xi[d]<=m) and (x+xi[d]>0)    and (y+yi[d]<=n) and (y+yi[d]>0)  do    begin      x:=x+xi[d];      y:=y+yi[d];      if (h<f[x,y,d]) and (a[x,y]<>B) then f[x,y,d]:=h;      if (y=y2) and (x=x2) then begin if h<ans then ans:=h; exit; end;      b[x,y,d]:=false;    end;  end;  if (a[x,y]<>B) then begin x:=x+xi[d];y:=y+yi[d]; end;  if a[x,y]=B then  begin    if d=1 then    begin     dec(x);     if (a[x+xi[3],y+yi[3]]<>B) then dfs(h+1,x,y,3);     if (a[x+xi[4],y+yi[4]]<>B) then dfs(h+1,x,y,4);    end;    if d=2 then    begin     inc(x);     if (a[x+xi[3],y+yi[3]]<>B) then dfs(h+1,x,y,3);     if (a[x+xi[4],y+yi[4]]<>B) then dfs(h+1,x,y,4);    end;    if d=3 then    begin     dec(y);     if (a[x+xi[1],y+yi[1]]<>B) then dfs(h+1,x,y,1);     if (a[x+xi[2],y+yi[2]]<>B) then dfs(h+1,x,y,2);    end;    if d=4 then    begin     inc(y);     if (a[x+xi[1],y+yi[1]]<>B) then dfs(h+1,x,y,1);     if (a[x+xi[2],y+yi[2]]<>B) then dfs(h+1,x,y,2);    end;  end;end;begin  readln(m,n);  for i:=1 to m do  begin   for j:=1 to n-1 do   begin    read(a[i,j]);    if a[i,j]=S then    begin     x1:=i;y1:=j;    end;    if a[i,j]=E then    begin     x2:=i;y2:=j;    end;   end;   readln(a[i,n]);   if a[i,n]=S then    begin     x1:=i;y1:=n;    end;   if a[i,n]=E then    begin     x2:=i;y2:=n;    end;  end;  for i:=1 to m+1 do   for j:=1 to n+1  do   for k:=1 to 4 do    f[i,j,k]:=100;  fillchar(b,sizeof(b),true);  ans:=maxlongint;  a[x1,y1]:=.;  for d:=1 to 4 do  dfs(0,x1,y1,d);  if ans=maxlongint then  writeln(No) else  begin   writeln(Yes);   writeln(ans);  end;end.
丢一个吴桐的AC代码(pas)虽然我没有看完

 

结果