zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    HDU 1058 Humble Numbers
    HDU 1160 FatMouse's Speed
    HDU 1087 Super Jumping! Jumping! Jumping!
    HDU 1003 Max Sum
    HDU 1297 Children’s Queue
    UVA1584环状序列 Circular Sequence
    UVA442 矩阵链乘 Matrix Chain Multiplication
    DjangoModels修改后出现You are trying to add a non-nullable field 'download' to book without a default; we can't do that (the database needs something to populate existing rows). Please select a fix:
    opencv做的简单播放器
    c++文件流输入输出
  • 原文地址:https://www.cnblogs.com/c1299401227/p/5370770.html
Copyright © 2011-2022 走看看