zoukankan      html  css  js  c++  java
  • 洛谷 P1141 01迷宫

    题目:01迷宫

    网址:https://www.luogu.com.cn/problem/P1141

    题目描述

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

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

    输入格式

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

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

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

    输出格式

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

    输入输出样例
    输入
    2 2
    01
    10
    1 1
    2 2
    
    输出
    4
    4
    
    说明/提示

    所有格子互相可达。

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

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

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

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

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

    很不错的一道flood-fill题目,不过需要记忆化搜索。

    代码如下:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define maxn 1000 + 5
    #define pa pair <int , int>
    using namespace std;
    
    const int dx[4] = {-1 , 0 , 1 , 0} , dy[4] = {0 , 1 , 0 , -1};
    bool book[maxn][maxn];
    queue <pa> Q;
    int n , m , map[maxn][maxn] , dfn[maxn][maxn] , s[1001000] = {} , tot = 0;
    int bfs(int x , int y)
    {
    	int ans = 0;
    
    	while(!Q.empty()) Q.pop();
    	book[x][y] = true;
    	Q.push(make_pair(x , y));
    
    	while(!Q.empty())
    	{
    		pa node = Q.front();
    		x = node.first , y = node.second;
    		Q.pop();
    		dfn[x][y] = tot;
    		++ ans;
    		for(int i = 0; i < 4; ++ i) {
    			if(map[x][y] + map[x + dx[i]][y + dy[i]] == 1 && !book[x + dx[i]][y + dy[i]]) {
    				Q.push(make_pair(x + dx[i] , y + dy[i]));
    				book[x + dx[i]][y + dy[i]] = true;
    			}
    		}
    	}
    
    	return ans;
    }
    
    int main()
    {
    	memset(map , -1 , sizeof(map));
    	memset(dfn , 0 , sizeof(dfn));
    	scanf("%d %d" , &n , &m);
    	int i , x , y , j;
    	for(i = 1; i <= n; ++ i)
    		for(j = 1; j <= n; ++ j) scanf("%1d" , &map[i][j]);
    	for(i = 1; i <= n; ++ i) {
    		for(j = 1; j <= n; ++ j) {
    			if(!dfn[i][j]) {
    				++ tot;
    				s[tot] = bfs(i , j);
    			}
    		}
    	}
    	for(i = 0; i < m; ++ i)
    	{
    		scanf("%d %d" , &x , &y);
    		printf("%d
    " , s[dfn[x][y]]);
    	}
    	return 0;
    }
    

    这道题启示我,若题意明确要 动态查询 的时候,可以考虑将其变为记忆化搜索。

  • 相关阅读:
    机器学习学习笔记之二:决策树
    机器学习学习笔记之一:K最近邻算法(KNN)
    Shell脚本编程中的几个问题
    Linux服务器配置git服务
    Ubuntu下安装IDA pro
    网络扫描(二)
    网络扫描(一)
    Docker学习过程中遇到的问题及解决方法
    CentOS7中升级Docker版本
    解决CentOS无法解析域名的问题
  • 原文地址:https://www.cnblogs.com/zach20040914/p/12814327.html
Copyright © 2011-2022 走看看