• 问题 1923: [蓝桥杯][算法提高VIP]学霸的迷宫 (BFS)


    题目链接:https://www.dotcpp.com/oj/problem1923.html

    题目描述
    学霸抢走了大家的作业,班长为了帮同学们找回作业,决定去找学霸决斗。但学霸为了不要别人打扰,住在一个城堡里,城堡外面是一个二维的格子迷宫,要进城堡必须得先通过迷宫。因为班长还有妹子要陪,磨刀不误砍柴功,他为了节约时间,从线人那里搞到了迷宫的地图,准备提前计算最短的路线。可是他现在正向妹子解释这件事情,于是就委托你帮他找一条最短的路线。
    输入
    第一行两个整数n, m,为迷宫的长宽。
    接下来n行,每行m个数,数之间没有间隔,为0或1中的一个。0表示这个格子可以通过,1表示不可以。假设你现在已经在迷宫坐标(1,1)的地方,即左上角,迷宫的出口在(n,m)。每次移动时只能向上下左右4个方向移动到另外一个可以通过的格子里,每次移动算一步。数据保证(1,1),(n,m)可以通过。
    输出
    第一行一个数为需要的最少步数K。
    第二行K个字符,每个字符∈{U,D,L,R},分别表示上下左右。如果有多条长度相同的最短路径,选择在此表示方法下字典序最小的一个。
    样例输入
    3 3
    001
    100
    110
    样例输出
    4
    RDRD

    和一般的算出最短路径不同的是,还要记录方向,之前省赛的时候没有做出来,现在按照大佬的思路做了下(用一个字符串存方向,每次放一个字母),但是只过了83%的样例,歇会儿再改改(第一个是错误版本,第二个是正确版本)

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <string>
     4 #include <cstring>
     5 #include <queue>
     6 #include <stack>
     7 using namespace std;
     8 const int INF=0x3f3f3f3f;
     9 typedef pair<int,int> P;
    10 int N,M;
    11 int d[1005][1005];
    12 char a[1005][1005];
    13 int dx[4]={1,0,0,-1};
    14 int dy[4]={0,-1,1,0};
    15 char pos[4]={'D','L','R','U'};
    16 int sx,sy,gx,gy;
    17 int x,y,nx,ny;
    18 void bfs()
    19 {
    20     memset(d,INF,sizeof(d));
    21     sx=0,sy=0,gx=N-1,gy=M-1;
    22     string s="";
    23     queue<P> que;
    24     que.push(P(sx,sy));
    25     d[sx][sy]=0;
    26     while(!que.empty()){
    27         P p=que.front();
    28         que.pop();
    29         x=p.first,y=p.second;
    30         if(x==gx&&y==gy) break;
    31         for(int i=0;i<4;i++){
    32             nx=x+dx[i],ny=y+dy[i];
    33             if(nx>=0&&nx<N&&ny>=0&&ny<M&&a[nx][ny]!='1'&&d[nx][ny]==INF){
    34                 s+=pos[i];
    35                 que.push(P(nx,ny));
    36                 d[nx][ny]=d[x][y]+1;
    37             }
    38         }
    39     }
    40     cout<<d[gx][gy]<<endl;
    41     cout<<s<<endl;
    42 }
    43 int main()
    44 {
    45     while(cin>>N>>M){
    46         for(int i=0;i<N;i++){
    47             for(int j=0;j<M;j++){
    48                 cin>>a[i][j];
    49             }
    50         }
    51         bfs();
    52     }
    53     return 0;
    54 }

     对比了下过了的大佬的代码,自己又改了改,过了。。。区别在于需要给每个结点一个字符串记录路径方向,而不是只用一个字符串记录。。。

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <string>
     4 #include <cstring>
     5 #include <queue>
     6 #include <stack>
     7 using namespace std;
     8 const int INF=0x3f3f3f3f;
     9 struct node
    10 {
    11     int first,second;
    12     string s;
    13 };
    14 int N,M;
    15 int d[1005][1005];
    16 char a[1005][1005];
    17 int dx[4]={1,0,0,-1};
    18 int dy[4]={0,-1,1,0};
    19 char pos[4]={'D','L','R','U'};
    20 int sx,sy,gx,gy;
    21 int x,y,nx,ny;
    22 void bfs()
    23 {
    24     memset(d,INF,sizeof(d));
    25     sx=0,sy=0,gx=N-1,gy=M-1;
    26     queue<node> que;
    27     node p;
    28     p.first=sx,p.second=sy,p.s="";
    29     que.push(p);
    30     d[p.first][p.second]=0;
    31     node k,l;
    32     while(!que.empty()){
    33         k=que.front();
    34         que.pop();
    35         x=k.first,y=k.second;
    36         if(x==gx&&y==gy) break;
    37         for(int i=0;i<4;i++){
    38             nx=x+dx[i],ny=y+dy[i];
    39             if(nx>=0&&nx<N&&ny>=0&&ny<M&&a[nx][ny]!='1'&&d[nx][ny]==INF){
    40                 l.first=nx,l.second=ny,l.s=k.s+pos[i];
    41                 que.push(l);
    42                 d[nx][ny]=d[x][y]+1;
    43             }
    44         }
    45     }
    46     cout<<d[gx][gy]<<endl;
    47     cout<<k.s<<endl;
    48 }
    49 int main()
    50 {
    51     while(cin>>N>>M){
    52         for(int i=0;i<N;i++){
    53             for(int j=0;j<M;j++){
    54                 cin>>a[i][j];
    55             }
    56         }
    57         bfs();
    58     }
    59     return 0;
    60 }
  • 相关阅读:
    告别恼人的水平滚动条——滚动条宽度到底是多少?
    A用户控件包含B用户控件,在B里头如何取得A控件
    ASP.NET URL重写
    Asp.net(c#)发送电子邮件
    优化网站性能的14条规则
    复杂度的来源—高性能
    构建命令行式交易区块链应用
    复杂度来源—低成本、安全、规模
    实现一个简易的区块链
    复杂度来源—可扩展性
  • 原文地址:https://www.cnblogs.com/shixinzei/p/10748301.html
Copyright © 2020-2023  润新知