• [蓝桥杯2019初赛]迷宫-DFS、BFS两种方法


    迷宫问题的最短路,加最小字典序
    在这里插入图片描述
    迷宫文件maze.txt传送门
    作者写的2019年B组蓝桥杯解集
    .
    .
    .

    DFS的版本

    #include<iostream>
    #include<cstring>
    using namespace std;
    const int ax[4]={0,0,1,-1};
    const int ay[4]={1,-1,0,0};
    const char dir[5]={'R','L','D','U'};
    int maze[60][60],mins[60][60];
    char a[2000];
    int best;
    string ans;
    bool judge(int x,int y) {//判断这个点是否越界,是否走过。
    	if(x>0&&x<=30&&y>0&&y<=50&&!maze[x][y])
    		return true;
    	return false;
    }
    void dfs(int x,int y,int pos) {
    	if(pos>best)
    		return ;
    	if(x==30&&y==50) {
    		string temp;
    			for(int i=1;i<pos;i++)
    				temp+=a[i];
    		if(pos<best) {//是最短的路
    			ans=temp;
    			best=pos;
    		}
    		else if(pos==best&&temp<ans)	ans=temp;//在实现路时最短的同时,保证字典序最小。
    		return ;
    	}
    	for(int i=0;i<4;i++) {
    		int tempx=x+ax[i];
    		int tempy=y+ay[i];
    		if(judge(tempx,tempy)&&pos+1<=mins[tempx][tempy]) {
    			maze[tempx][tempy]=1;
    			mins[tempx][tempy]=pos+1;
    			a[pos]=dir[i];
    			dfs(tempx,tempy,pos+1);
    			maze[tempx][tempy]=0;//回溯找短的路,或者时字典序最小的。
    		}
    	}
    }
    int main()
    {
    	freopen("D:\MY\ce.txt","r",stdin);
    	memset(mins,1,sizeof(mins));
    	best=1<<28;
    	for(int i=1;i<=30;i++)
    		for(int j=1;j<=50;j++) {
    			char t;
    			cin>>t;
    			maze[i][j]=t-'0'; 
    		}
    	maze[1][1]=1;
    	dfs(1,1,1);
    	cout<<ans<<endl;
    	return 0;
    }
    

    其中最重要的就是数组mins,这里记录了从起始位置到这里的最短步数,
    l
    l当这个点在可以到达终点的路径上时,也有可能有多种方式到这个点,所以一点更要保证时最小的步数到可以到达终点的路径上的点。

    .
    .
    .
    BFS版本

    #include<iostream>
    #include<cstring>
    #include<queue>
    const int ax[4]={1,0,0,-1};
    const int ay[4]={0,-1,1,0};
    const char dir[5]={'D','L','R','U'};
    int maze[40][60];
    using namespace std;
    struct point {
    	int x,y;
    	string ans;
    	point(int a,int b,string c):x(a),y(b),ans(c){}
    };
    bool judge(int x,int y) {
    	if(x>0&&x<=30&&y>0&&y<=50&&!maze[x][y])
    		return true;
    	return false;
    }
    void bfs() {
    	queue<point>ans;
    	ans.push(point(1,1,""));
    	maze[1][1]=1;
    	while(!ans.empty()) {
    		point temp=ans.front();
    		ans.pop();
    		if(temp.x==30&&temp.y==50) {
    			cout<<temp.ans<<endl;
    			return ;
    		}
    		for(int i=0;i<4;i++) {
    			int tempx=temp.x+ax[i];
    			int tempy=temp.y+ay[i];
    			if(judge(tempx,tempy)) {
    				maze[tempx][tempy]=1;
    				ans.push(point(tempx,tempy,temp.ans+dir[i]));
    			}
    		}
    	}
    }
    int main() {
    	freopen("D:\MY\ce.txt","r",stdin);
    	for(int i=1;i<=30;i++)
    		for(int j=1;j<=50;j++) {
    			char t;
    			cin>>t;
    			maze[i][j]=t-'0'; 
    		}
    	bfs();
    	return 0;
    }
    

    这里就不用考虑回溯的问题,不用考虑是不是最短路的问题,但是可能有一个是不是字典序最小需要考虑,
    .
    于是我把这里的dir方向数组设置成了"D L R U"的顺序,保证了在步数最小的前提下最小字典序一定会最早出现。

    DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR
    *
    **
    **
    *


    还有一点要注意的就是,我这里 用的是int数组存地图,地图之间没有空格,一定要先用char读取,或者直接用char数组表示地图。
    .
    就因为这个,我抑郁了好久,一直不知道哪里错了。

  • 相关阅读:
    BeanUtils.copyProperties的用法
    Eclipse中GitLab的配置和使用入门
    认识与入门 Markdown
    mybatis基础配置
    动态规划-最长公共子串
    查找
    Entity Framework Code First ---EF Power Tool 和MySql一起使用遇到的问题
    使用TortoiseSVN碰到的几个问题(2)-冲突解决, 图标重载
    使用TortoiseSVN碰到的几个问题(1)-导入,提交,更新
    Asp.net MVC4 Step By Step(5)-使用Web API
  • 原文地址:https://www.cnblogs.com/lifehappy/p/12601204.html
Copyright © 2020-2023  润新知