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

    题目描述

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

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


    输入格式:

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

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

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

    输出格式:

    输入样例#1:

    2 2

    01
    10
    1 1
    2 2
    输出样例#1:
    4
    4

    说明


    所有格子互相可达。

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

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

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

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

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

    题目分析

    很普通的bfs题,但是注意到她的数据规模很大,要适当的优化。

    分析题过后,我们可以发现,迷宫当中可以互相到达的点,能够组成一个集合,且集合中的点能移动几个格子的个数都是相等的,

    另外,在输入矩阵时,数字之间没有空格,我们需要用scanf(“%1d”, &maze[i][j])来读取。

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    #include <queue>
    #include <string>
    #include <map>
    using namespace std;
    struct node {
    	int x, y;
    	node(int a, int b) {
    		x = a;
    		y = b;
    	}
    };
    int n, m;
    int maze[1000 + 2][1000 + 2];
    int dir[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
    int p_sum[1000 + 2][1000 + 2];//标记第i行j列的点,在哪个集合中
    int set[100000 + 2];//第i个集合中的点能走几步
    bool check(int x, int y) {
    	if (x < 0 || y < 0 || y >= n || x >= n)
    		return false;
    	return true;
    }
    int bfs(int index,int a, int b) {
    	int sum = 0;
    	queue<node> myq;
    	myq.push(node(a, b));
    	while (!myq.empty()) {
    		//出队
    		int x = myq.front().x;
    		int y = myq.front().y;
    		myq.pop();
    		//若已在集合中,则跳过
    		if (p_sum[x][y] != 0)
    			continue;
    		//将点加入集合
    		p_sum[x][y] = index;
    		sum++;
    		//枚举所有方向
    		for (int i = 0; i < 4; i++) {
    			int xx = x + dir[i][0];
    			int yy = y + dir[i][1];
    			if (check(xx, yy) && maze[x][y] != maze[xx][yy])
    				myq.push(node(xx, yy));
    		}
    	}
    	set[index] = sum;
    	return sum;
    }
    int main(){
    	scanf("%d %d
    ", &n, &m);
    	for (int i = 0; i < n; i++) {
    		for (int j = 0; j < n; j++) {
    			scanf("%1d", &maze[i][j]);
    		}
    	}
    	for (int i = 0; i < m; i++) {
    		int a, b;
    		scanf("%d %d", &a, &b);
    		if (p_sum[a - 1][b - 1])
    			cout << set[p_sum[a - 1][b - 1]] << endl;
    		else
    			cout << bfs(i + 1, a - 1, b - 1) << endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    tomcat配置通过域名直接访问项目首页步骤
    kafka配置参数
    nginx平滑升级
    redsi一主两从三哨兵
    kill
    lelnet爱一直在
    在linux中查看进程占用的端口号
    监控redis
    老猿学5G随笔:RAN、RAT以及anchor移动性锚点的概念
    老猿学5G随笔:5G网元功能体NF以及NF之间的两种接口--服务化接口和参考点
  • 原文地址:https://www.cnblogs.com/woxiaosade/p/10654238.html
Copyright © 2011-2022 走看看