zoukankan      html  css  js  c++  java
  • 【bfs】【中等难度】tyvj P1234

    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 0x7fffffff
    struct 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 0x7fffffff
    struct 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
    //       2
    
    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; /*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)虽然我没有看完

    结果

    noip忘记取模的痛
  • 相关阅读:
    ADO连接access和oracle的一个区别
    我的大救星——Oracle APEX 快速Web开发(鼠标点点即可开发出专业级Web应用)
    Sql Server 2008 R2 error:40 错误处理
    我的第一个WPF程序
    开源社会网络分析工具NodeXL介绍
    JavaScript学习笔记1之基础知识点
    JavaScript学习笔记6 之经典神坑题整理
    JavaScript学习笔记2之Tab切换
    变量声明和函数声明会提升到当前作用域顶部
    JavaScript学习笔记5 之 计时器 & scroll、offset、client系列属性 & 图片无缝滚动
  • 原文地址:https://www.cnblogs.com/seekdreamer/p/3917079.html
Copyright © 2011-2022 走看看