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

题目描述
有一个仅由数字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
提示
n <= 400

#include<bits/stdc++.h>
#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
int n,m,x,y,b[1001][1001],g,sc[100001];//b数组用于判断是否走过(值=-1)以及是在第几次询问时走的。sc数组代表该次询问总步数 
char a1[1001][1001];//用于输入 
void ddd(int x1,int y1,int z,int xc)//四个参数分别为横坐标、纵坐标、当前的值(0或1)、xc表示是第几次询问 
{
	if(x1<0||x1>=n||y1<0||y1>=n||b[x1][y1]!=(-1)||a1[x1][y1]-'0'!=z) return;
	//退出条件:1、越界;2、已访问过(b[i][j]!=-1);3、当前的值与上一个值一样
	//(因为在下面的递归中条件设为!z(即不一样,0变成1,1变成0) ,在这里再否定一下,双重否定为肯定,就是一样! 
    b[x1][y1]=xc;//标记该点已经被第xc次询问走过 
	sc[xc]++; //第xc次询问的步数加一步。 
	ddd(x1-1,y1,!z,xc);//“!z”表示当前值必须与上一个值不同! 
	ddd(x1+1,y1,!z,xc);
	ddd(x1,y1-1,!z,xc);
	ddd(x1,y1+1,!z,xc);
}
int main()
{
	//freopen("p1141.in","r",stdin);
    //freopen("p1141.out","w",stdout); 
	memset(b,-1,sizeof(b));  // b数组统一赋初值 
	cin>>n>>m;
	for(int i=0;i<=n-1;i++)
	for(int j=0;j<=n-1;j++)
	cin>>a1[i][j];
	for(int i=0;i<=m-1;i++)
	{
		cin>>x>>y;
		x--;y--;//因为数组默认都是从0开始的,而题目输出给定的要求是“第i行第j列”中的i和j明显从1开始,所以,一开始横纵坐标全部回调1
		//为什么不能直接从第1行第1列开始输入?因为第0行第0列的值不好判断,如果从1行第1列开始输入,那么第0行第0列的初始值不论是什么都与其他格子的值不同,这样就不好判断了 
		if(b[x][y]==-1) ddd(x,y,a1[x][y]-'0',i);//如果这个格子没有被走过,则开始DFS 
		else sc[i]=sc[b[x][y]];	//如果这个格子已经被走过,则直接输出走过的值,因为所有走过的都是相通的。 
	}
	for(int i=0;i<=m-1;i++) cout<<sc[i]<<endl;
	return 0;
}

转载于:
https://blog.youkuaiyun.com/zliang_ma/article/details/104434126

在C语言中,要模拟一个N×N大小迷宫并找到配送员从左上角到达右下角的路径,可以采用广度优先搜索(BFS算法。这里假设迷宫0表示可以通过,1表示墙壁。以下是基本的步骤: 1. 定义迷宫矩阵`maze[N][N]`,初始化配送员的位置`(0, 0)`。 2. 创建一个队列`queue`,并将起始位置添加到队列中。 3. 定义一个二维数组`visited[N][N]`来标记已经访问过的子,初始时只有起始点设为true。 4. 使用循环实现BFS: ```c while (!queue.empty()) { // 取出队首元素 (row, col) int row = queue.front().first; int col = queue.front().second; queue.pop(); // 如果当前位置是右下角,则找到了路径,返回结果 if (row == N - 1) { printf("Path found from (%d, %d) to (%d, %d)\n", 0, 0, row, col); break; } // 检查相邻的四个方向(上、下、左、右) if (isValidMove(row + 1, col, maze) && !visited[row + 1][col]) { visited[row + 1][col] = true; queue.push({row + 1, col}); } if (isValidMove(row, col + 1, maze) && !visited[row][col + 1]) { visited[row][col + 1] = true; queue.push({row, col + 1}); } if (isValidMove(row - 1, col, maze) && !visited[row - 1][col]) { visited[row - 1][col] = true; queue.push({row - 1, col}); } if (isValidMove(row, col - 1, maze) && !visited[row][col - 1] = true; queue.push({row, col - 1}); } } ``` 5. `isValidMove(int row, int col, int maze[][])` 函数用于检查当前位置是否合法,即是否存在墙壁或者越界: ```c bool isValidMove(int row, int col, int maze[][N]) { return row >= 0 && row < N && col >= 0 && col < N && maze[row][col] == 0; } ``` 如果找不到路径,说明迷宫中存在障碍物使得配送员无法到达右下角。注意,在实际应用中,可能还需要处理更复杂的迷宫条件,比如有门可以打开或关闭等。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值