• 69.广搜练习:  最少转弯问题(TURN)



    【问题描述】

            给出一张地图,这张地图被分为n×mn,m<=100)个方块,任何一个方块不是平地就是高山。平地可以通过,高山则不能。现在你处在地图的(x1,y1)这块平地,问:你至少需要拐几个弯才能到达目的地(x2,y2)?你只能沿着水平和垂直方向的平地上行进,拐弯次数就等于行进方向的改变(从水平到垂直或从垂直到水平)的次数。例如:如图,最少的拐弯次数为5

     

     

    69.广搜练习: <wbr> <wbr>最少转弯问题(TURN)

    【输入格式】

    1行:  m

    2n+1行:整个地图地形描述(0:空地;1:高山),

    如(图)第2行地形描述为:1 0 0 0 0 1 0

                   3行地形描述为:0 0 1 0 1 0 0

                   ……

    n+2行:x1  y1  x2  y2  (分别为起点、终点坐标)

    【输出格式】

    s (即最少的拐弯次数)

    【输入输出样例】(见图):

    TURN.IN

    TURN.OUT

    5 7

    1 0 0 0 0 1 0

    0 0 1 0 1 0 0

    0 0 0 0 1 0 1

    0 1 1 0 0 0 0

    0 0 0 0 1 1 0

    1 3 1 7

    5

    基本思路:利用广搜寻找一条从起点到终点最短路径,利用pre[]数组一直

    错误代码:(最先找到的最短路径不一定是拐弯最少的):

    #include

    #include

    using namespace std;

    #include

    struct Poi{

           int x,y;

    };

    Poi dl[10001];

    int xq,yq,xz,yz,n,m,jz[101][101],pre[101*101],t=0;

    int xx[]={0,0,1,-1};

    int yy[]={1,-1,0,0};

    long long sum=0;

    int head=0,tail=1;

    void BFS()

    {

           dl[tail].x=xq;

           dl[tail].y=yq;

           pre[tail]=0;

           jz[xq][yq]=1;

           while(head

           {

                  ++head;

                  int x0=dl[head].x,y0=dl[head].y;

                  for(int i=0;i<4;++i)

               {

                      int x1=x0+xx[i],y1=y0+yy[i];

                      if(x1>=1&&x1<=n&&y1>=1&&y1<=m&&!jz[x1][y1])

                      {

                             jz[x1][y1]=1;

                             ++tail;

                             dl[tail].x=x1;

                             dl[tail].y=y1;

                             pre[tail]=head;

                         }

                         if(dl[tail].x==xz&&dl[tail].y==yz)

                         {

                                head=tail;

                                break;

                         }

                  }

           }

    }

    void count()

    {

           for(int i=tail;pre[pre[i]]!=0;i=pre[i])

           {

                  if(dl[i].x!=dl[pre[pre[i]]].x&&dl[i].y!=dl[pre[pre[i]]].y)

                  sum++;

           }

    }

    void input()

    {

           scanf("%d%d",&n,&m);

           for(int i=1;i<=n;++i)

             for(int j=1;j<=m;++j)

             scanf("%d",&jz[i][j]);

           scanf("%d%d%d%d",&xq,&yq,&xz,&yz);

       

    }

    int main()

    {

           input();

           BFS();

           count();

           printf("%d",sum);

           return 0;

    }

    特例:

    5 7

    0 0 0 1 0 0 0

    0 1 0 0 0 1 0

    0 0 1 1 1 0 0

    0 1 0 0 0 0 0

    0 0 0 0 0 0 0

    1 1 1 7

    正确答案:是2错误答案:4(是找到最短路)

    正确代码:

     

    #include

    #include

    using namespace std;

    #include

    const int INF=999999;

    int n,m,jz[101][101];

    struct Dl{

           int x,y;

    };

    Dl dl[101*101];

    int xq,xz,yz,yq,turn[101][101],x0,y0;int k;int head=0,tail=1;

    void input()

    {

           scanf("%d%d",&n,&m);

           for(int i=1;i<=n;++i)

             for(int j=1;j<=m;++j)

             scanf("%d",&jz[i][j]);

             scanf("%d%d%d%d",&xq,&yq,&xz,&yz);

           memset(turn,99,sizeof(turn));

    }

    void search(int i,int j,int p)

    {

           k+=p;

           if(turn[i][j]<1667457891) return;//说明之前已经找过了

           ++tail;dl[tail].x=i;

           dl[tail].y=j;

           turn[i][j]=turn[x0][y0]+1;//再找到下个点时,一定已经拐弯了

    }

    void BFS()

    {

           dl[tail].x=xq;

           dl[tail].y=yq;

           turn[xq][yq]=-1;//把初值设为-1,才把与起点共线的步数设为0

           while(head

           {

                  ++head;

                  x0=dl[head].x,y0=dl[head].y;

                  k=x0+1;while(k<=n&&jz[k][y0]==0) search(k,y0,1);//只要是在一条直线上的就一次走到底,拐弯数最少

                  k=x0-1;while(k>=1&&jz[k][y0]==0) search(k,y0,-1);

                  k=y0+1;while(k<=m&&jz[x0][k]==0) search(x0,k,1);

                  k=y0-1;while(k>=1&&jz[x0][k]==0) search(x0,k,-1);

                 

           }

    }

    int main()

    {

           input();

           BFS();

        printf("%d",turn[xz][yz]);

           return 0;

    }

    //1667457891

  • 相关阅读:
    网络流24题-运输问题
    ASP.NET API
    面向对象理解
    冒泡排序
    HTTP Header 缓存
    HTTP Header
    Flask学习笔记07之模板渲染
    Flask学习笔记06之@before_request请求之前执行
    Flask报错:AssertionError: View function mapping is overwriting an existing endpoint function: inner
    装饰器03之多个装饰器的执行顺序
  • 原文地址:https://www.cnblogs.com/csgc0131123/p/5290387.html
Copyright © 2020-2023  润新知