zoukankan      html  css  js  c++  java
  • 关于地图遍历问题的总结

    关于地图遍历问题的总结

    先来看一道例题:

    洛谷 AT1350 深さ優先探索

    题目传送门

    题解传送门

    题意翻译

    高桥先生住的小区是长方形的,被划分成一个个格子。高桥先生想从家里去鱼店,高桥先生每次可以走到他前后左右四个格子中的其中一个,但不能斜着走,也不能走出小区。

    现在给出地图:

    s:代表高桥先生的家

    g:代表鱼店

    .:代表道路

    #:代表墙壁

    高桥先生不能穿过墙壁。

    输入:第一行输入n(1<=n<=500),m(1<=m<=500)代表小区的长和宽,接下来n行每行m个字符,描述小区中的每个格子。

    输出:如果高桥先生能到达鱼店,输出"Yes",否则输出"No"。


    地图遍历问题

    这种需要按要求从一个点出发“走迷宫”的题,本蒟蒻给它起了个名字叫做地图遍历问题。

    应该是非常基础的深搜例题,只是在此做个总结,顺便复习一下深搜。

    首先是思路:

    深搜的定义大家应该都有所了解。但是这种定义方式是基于树和图的深度优先遍历的,比较容易被大家理解。所以应该有好多小伙伴都是像本蒟蒻一样蒙圈:这种题无图无树,和深搜有关系么?

    这就需要一个思维转换:构建搜索树

    所谓搜索树,就是把乍一看没法用深搜解决的问题抽象成一棵树,不是说深搜是对树和图的深度优先遍历么?那我把这个问题变成一个图,不就解决了么?

    那好,我们开始抽象:

    一张地图,对于每一个点(就是矩阵的每一个坐标),它有四个选择可走:上下左右。那么,我们可以将其抽象成一个每个节点有四个子节点的图。(当然,边界节点和墙都是除外的)

    有了这个思路,就可以进行搜索的代码模拟了。

    代码思路

    首先是“指南针”——方向数组,这个数组帮助我们更改点的坐标,使得搜索有序进行。

    int dx[]={0,0,0,-1,1};
    int dy[]={0,1,-1,0,0};
    

    然后是正常的搜索,搜索的函数可以归纳成这个模板:

    void dfs(int x,int y)
    {
        if(target)
            return answer;
        for(int i=1;i<=4;i++)
        {
            int xx=x+dx[i];
            int yy=y+dy[i];
            if(condition)
                continue;
            dfs(xx,yy);
        }
    }
    

    其中target是目标条件,answer是答案或者处理,condition是继续搜索的条件,也可以理解为剪枝。

    那么,这个继续搜索的条件也有一个一般套路,就是我们需要让当前的((xx,yy))点不越界,这个条件是所有“地图遍历”问题都必须要有的,其他的限制条件依题意再规范。

    那么,以上的例题就可以得到求解,代码是这样的:

    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int maxn=510;
    int n,m;
    char map[maxn][maxn];
    bool v[maxn][maxn];
    int dx[]={0,0,0,-1,1};
    int dy[]={0,1,-1,0,0};
    int a,b,c,d;
    void dfs(int x,int y)
    {
    	v[x][y]=1;
    	for(int i=1;i<=4;i++)
    	{
    		int xx=x+dx[i];
    		int yy=y+dy[i];
    		if(xx<1 || xx>n || yy<1 || yy>m || map[xx][yy]=='#' || v[xx][yy])
    			continue;
    		dfs(xx,yy);
    	}
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    		{
    			cin>>map[i][j];
    			if(map[i][j]=='s')
    				a=i,b=j;
    			if(map[i][j]=='g')
    				c=i,d=j;
    		}
    	dfs(a,b);
    	if(v[c][d])
    	{
    		printf("Yes");
    		return 0;
    	}
    	else
    	{
    		printf("No");
    		return 0;
    	}
    }
    
  • 相关阅读:
    Codeforces Round #652 (Div. 2) A. FashionabLee(几何)
    轻量应用服务器如何通过修改apache配置文件实现非https的访问多域名到不同子目录程序?
    在Windows环境下使用hexo搭建博客以及部署到gitee / github
    使用WordPress搭建个人手机博客(阿里云)
    访问自己服务器的ip地址
    php环境无法上传文件的解决方法
    SSRF漏洞
    CSRF全家桶(含义,防御,攻击)
    JS实现HTML实体与字符的相互转换
    CentOS系统下载及应用部署
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13220891.html
Copyright © 2011-2022 走看看