当前位置: 首页 > news >正文

[LuoguP1141]01迷宫

                1141 01迷宫

题目描述

有一个仅由数字0与1组成的n×n格迷宫。若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上。

你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。

输入输出格式

输入格式:

 

输入的第1行为两个正整数n,m。

下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格。

接下来m行,每行2个用空格分隔的正整数i,j,对应了迷宫中第i行第j列的一个格子,询问从这一格开始能移动到多少格。

 

输出格式:

 

输出包括m行,对于每个询问输出相应答案。

 

输入输出样例

输入样例#1: 复制
2 2
01
10
1 1
2 2
输出样例#1: 复制
4
4

说明

所有格子互相可达。

对于20%的数据,n≤10;

对于40%的数据,n≤50;

对于50%的数据,m≤5;

对于60%的数据,n≤100,m≤100;

对于100%的数据,n≤1000,m≤100000。

 

大家看到题目可能想起了深搜的板子题:迷宫【详见“迷宫”】,但这个题目和迷宫那个题显然不是很一样,但是根据题目来看我们也自然而然能够想到深搜DFS。首先这个题基本和迷宫问题没有什么很大的区别,只是少了一个条件,多了另外一个条件:不用判断障碍物,但必须要是在0上走1,在1上走0,也就是你下一次走的和你现在走的不能一样,而且这里依然要判断重复路径和越界。

首先和迷宫一样,我们定义一个dx[4],dy[4]用来循环行走的方向,也就是下一次行走的位置,分别是:

dx[4]={1,-1,0,0},dy[4]={0,0,1,-1},当然也可以定义一个二维的数组b[4][2]={{1,0}{-1,0}{0,1}{0,-1}},接下来定义一个res数组用来标记[x][y]这个点是否已经走过了,如果是,那么直接跳过,如果不是的话,再进行下一步。

下面附上代码:

#include<bits/stdc++.h>//万能头文件,但似乎会使运行变慢,因为无用库太多 
using namespace std;
int a[1001][1001];//01数组 
int res[1001][1001];//答案数组 
int lin[1000001][2];//临时的坐标数组 
int n, m, pl;//pl是当前区块连通的点数 
int b[4][2] = {{0,1},{1,0},{0,-1},{-1,0}}; //上下左右四方向的深搜 
void dfs(int x, int y){
    pl++;//来到一个新的点,下面存储该点坐标 
    lin[pl][0] = x; 
    lin[pl][1] = y;
    res[x][y] = 1;//这个点已经走过了,只是为了防止一趟深搜内部走重复点,所以不需要赋为pl 
    for(int i = 0; i <= 3; i++){
        int u = x + b[i][0];//u,v即为目的地 
        int v = y + b[i][1];
        if(u < 1 || u > n || v < 1 || v > n)//超出边界? 
            continue;
        if(res[u][v] > 0) continue;//走到过了 ? 
        if(a[u][v] == a[x][y]) continue;//根据题意,并不能走? 
        dfs(u, v);//以上条件都不满足才向下搜索 
    }
}
int main(){
    memset(res, 0, sizeof(res));//清空答案数组 
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            scanf("%1d", &a[i][j]);//%1d,限字宽,读入方便 
    for(int i = 1; i <= m; i++){
        pl = 0;//重置pl 
        int x, y;
        scanf("%d %d", &x, &y);
        if(res[x][y] > 0){//已经有答案 
            printf("%d\n", res[x][y]);
            continue;
        }
        dfs(x, y);
        for(int j = 1; j <= pl; j++)
            res[lin[j][0]][lin[j][1]] = pl; //依据坐标数组,为答案数组填上pl 
        printf("%d\n", pl);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/Yeasio-Nein/p/P1141.html

相关文章:

  • webpack学习笔记1
  • POJ2187 旋转卡壳 求最长直径
  • 《Java并发编程的艺术》--Java中的锁
  • win10 vs2015源码编译tesseract4.0
  • Go语言备忘录(2):反射的原理与使用详解
  • ubuntu16.04 更换源
  • Django中间件middleware
  • 结构图
  • libimobiledevice --Mingw32交叉编译
  • 在c:forEach作用域外使用标签所产生的值
  • 04-手机套餐:建造者模式
  • css总结1:position定位:absolute/relative/fixed
  • zzw原创_非root用户启动apache的问题解决(非root用户启动apache的1024以下端口)
  • SQL循环语句 详解
  • OpenCV问题集锦
  • Github访问慢解决办法
  • k个最大的数及变种小结
  • PHP面试之三:MySQL数据库
  • VuePress 静态网站生成
  • 服务器之间,相同帐号,实现免密钥登录
  • 回流、重绘及其优化
  • 机器学习中为什么要做归一化normalization
  • 基于axios的vue插件,让http请求更简单
  • 一份游戏开发学习路线
  • 最简单的无缝轮播
  • mysql面试题分组并合并列
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (31)对象的克隆
  • (二)PySpark3:SparkSQL编程
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (四)c52学习之旅-流水LED灯
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (转)shell中括号的特殊用法 linux if多条件判断
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .NET Core 2.1路线图
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .NET大文件上传知识整理
  • .NET框架
  • .net网站发布-允许更新此预编译站点
  • .Net中ListT 泛型转成DataTable、DataSet
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • @angular/cli项目构建--Dynamic.Form
  • @Pointcut 使用
  • [ vulhub漏洞复现篇 ] AppWeb认证绕过漏洞(CVE-2018-8715)
  • [⑧ADRV902x]: Digital Pre-Distortion (DPD)学习笔记
  • [BPU部署教程] 教你搞定YOLOV5部署 (版本: 6.2)
  • [C# 基础知识系列]专题十六:Linq介绍
  • [C++] sqlite3_get_table 的使用
  • [hdu 4552] 怪盗基德的挑战书
  • [hive] sql中distinct的用法和注意事项
  • [J2ME]如何替换Google Map静态地图自带的Marker
  • [openGL]在ubuntu20.06上搭建openGL环境
  • [Redis实战]分布式锁-redission