• HDU 逃离迷宫 (bfs)


    题面

    Problem Description
      给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?

    Input
      第1行为一个整数t (1 ≤ t ≤ 100),表示测试数据的个数,接下来为t组测试数据,每组测试数据中,   第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符'.'表示该位置为空地,字符'*'表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x[sub]1[/sub], y[sub]1[/sub], x[sub]2[/sub], y[sub]2[/sub] (1 ≤ k ≤ 10, 1 ≤ x[sub]1[/sub], x[sub]2[/sub] ≤ n, 1 ≤ y[sub]1[/sub], y[sub]2[/sub] ≤ m),其中k表示gloria最多能转的弯数,(x[sub]1[/sub], y[sub]1[/sub]), (x[sub]2[/sub], y[sub]2[/sub])表示两个位置,其中x[sub]1[/sub],x[sub]2[/sub]对应列,y[sub]1[/sub], y[sub]2[/sub]对应行。

    Output
      每组测试数据对应为一行,若gloria能从一个位置走到另外一个位置,输出“yes”,否则输出“no”。

    Sample Input
    2
    5 5
    ...**
    *..
    .....
    .....
    ....
    1 1 1 1 3
    5 5
    ...

    *.
    *.
    .....
    .....
    *....
    2 1 1 1 3

    Sample Output
    no
    yes

    思路

    bfs,无非在这里的话,我们有一个转弯的数量的限制,那首先我们想到的肯定是暴力的去做,直接判断这一步和下一步的方向一不一样,如果不一样就在改变的方向数目里面加上1,如果存在改变数目小于要求数目并且可以到达的话,那么就返回true,但是我写的这个做法wa了好几发(裂开)。我们换个思路想一下,我要求最小转弯数,那么我直接一条路走到底,就是我们以最小的转弯数换取最远的行走距离不就可以了。

    代码实现

    贴一下我的错误代码(有大佬可以帮忙改一下啊)

    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int maxn=101;
    int n,m,sx,sy,ex,ey,num;
    int vis[maxn][maxn];
    char maze[maxn][maxn];
    int moves[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
    struct node {
       int x,y;
       pair <int ,int> p;
       int changed;
    };
    bool  bfs (int x,int y) {
       queue<node> q;
       node now,temp;
       now.x=x; now.y=y;  now.changed=-1;
       now.p=make_pair(0,0);
       q.push (now);
       vis[x][y]=1;
       while (!q.empty()) {
          now=q.front();
          q.pop();
          if (now.x==ex&&now.y==ey) return true;
          for (int i=0;i<4;i++) {
             int nx=now.x+moves[i][0];
             int ny=now.y+moves[i][1];
             if (moves[i][0]!=now.p.first||moves[i][1]!=now.p.second) temp.changed=now.changed+1;
             temp.p=make_pair (nx-now.x,ny-now.y);
             if (nx<=n&&ny<=m&&nx>=1&&ny>=1&&vis[nx][ny]==0&&temp.changed<=num) {
                vis[nx][ny]=1;
                temp.x=nx; temp.y=ny;
                q.push (temp);
             }
          }
       }
       return false;
    } 
    int main () {
       int t;
       cin>>t;
       while (t--) {
          memset (vis,0,sizeof (vis));
          cin>>n>>m;
          for (int i=1;i<=n;i++) {
           getchar ();
           for (int j=1;j<=m;j++) {
              cin>>maze[i][j];
              if (maze[i][j]=='*') vis[i][j]=1;
           }
          }
          cin>>num>>sy>>sx>>ey>>ex;
          bool flag=bfs (sx,sy);
          if (flag) cout<<"yes"<<endl;
          else cout<<"no"<<endl;
       }
       return 0;
    }
    

    下面是ac代码

    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int maxn=101;
    int n,m,sx,sy,ex,ey,num;
    int vis[maxn][maxn];
    char maze[maxn][maxn];
    int moves[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
    struct node {
       int x,y,step;
    };
    bool check (node x) {
       if (x.x>=1&&x.y>=1&&x.x<=n&&x.y<=m&&maze[x.x][x.y]=='.') return 1;
       return 0; 
    }
    int bfs () {
       memset (vis,0,sizeof (vis));
       node temp,now;
       now.x=sx; now.y=sy;
       now.step=-1;
       queue <node> q;
       q.push (now);
       vis[now.x][now.y]=1;
       while (!q.empty()) {
          now=q.front();
          q.pop();
          if (now.x==ex&&now.y==ey) return max(0,now.step);
          for (int i=0;i<4;i++) {
             temp=now;
             temp.x+=moves[i][0];
             temp.y+=moves[i][1];
             temp.step=now.step+1;
             while (check(temp)) {
                if (vis[temp.x][temp.y]==0) {
                   q.push (temp);
                   vis[temp.x][temp.y]=1;
                }
                temp.x+=moves[i][0];
                temp.y+=moves[i][1];
             }
          }
       }
       return 999999;
    }
    int main () {
       int t;
       cin>>t;
       while (t--) {
          cin>>n>>m;
          for (int i=1;i<=n;i++) 
           for (int j=1;j<=m;j++) {
              cin>>maze[i][j];
           }
           cin>>num>>sy>>sx>>ey>>ex;
           int ans=bfs ();
           if (ans<=num) cout<<"yes"<<endl;
           else cout<<"no"<<endl;      
       }
       return 0;
    }
    
  • 相关阅读:
    旋转数组求最小值
    docker
    php爬虫
    docker,docker-compose 安装
    ReactPHP
    Workerman了解一下
    ubantu 运行.sh 脚本的问题
    ubantu 文件权限 Permission denied
    ubantu 文件属性
    mysql命令行中执行sql的几种方式总结
  • 原文地址:https://www.cnblogs.com/hhlya/p/13259369.html
Copyright © 2020-2023  润新知