OJ题——迷宫问题

🍬个人主页:Yanni.—

🌈数据结构:Data Structure.​​​​​​

🎂C语言笔记:C Language Notes

🏀OJ题分享: Topic Sharing

前言:

在笔试或者竞赛的过程中,经常会遇到迷宫问题,今天用c语言给大家带来初入迷宫的思路,以及一些复杂条件增加的迷宫问题,相信大家看完之后会收获满满!

基础迷宫

迷宫问题__牛客网 (nowcoder.com)

这道OJ题曾经是百度某一年的其中一个笔试题,迷宫问题的本质就是一个图遍历问题,从起点开始不断四个方向探索,直到走到出口,走的过程我们可以借助数据结构-栈来记录走过路径的坐标。

栈记录坐标有两方面的作用:

1.记录走过的路径

2.便于走到死路时进行回溯找其他的通路

创建迷宫

我们把迷宫想象成xy坐标轴上的坐标,创造出一个二维数组,考虑到空间需要自己输入,所以我们这里开辟动态二维数组,要开辟动态二维数组,有两个操作。

1.创造指针数组

2.在指针数组的基础上开辟动态数组空间

typedef struct postion
{
	int row;
	int col;
}PT;
int main()
{
	int N = 0, M = 0;
	while (scanf("%d%d", &N, &M) != EOF)
	{
		//要开辟二维数组,首先开辟指针数组
		int** maze = (int**)malloc(sizeof(int*) * N);
		//开辟每条数组的空间
		for (int i = 0; i < N; i++)
		{
			maze[i] = (int*)malloc(sizeof(int) * M);
		}
		//二维数组的输入
		for (int i = 0; i < N; i++)
		{
			for (int j = 0; j < M; j++)
			{
				scanf("%d", &maze[i][j]);
			}
		}
		PtintMaze(maze, N, M);
		StackInit(&path);
		PT entry = { 0,0 };
		if (GetMazePath(maze, N, M, entry))
		{
			PrintPath(&path);
		}
		else {
			printf("没有找到通路");
		}
		StackDestory(&path);

		//二维数组的销毁
		for (int i = 0; i < N; i++)
		{
			free(maze[i]);
		}
		free(maze);
		maze = NULL;
	}
	retu
### 关于东方博宜OJ 1010目解决方案 对于东方博宜OJ 1010目的描述涉及迷宫问题,其中需要解决的是在一个限定时间内找到从起点到终点的路径。此问题可以通过深度优先搜索(Depth First Search, DFS)来实现求解[^3]。 #### 迷宫结构解析 给定的迷宫由字符构成,具体如下: - `X` 表示不可穿越的墙壁; - `S` 是小狗出发的位置; - `D` 标识着出口位置; - `.` 则代表可以自由移动的空间。 这些元素共同构成了一个二维数组形式的地图,用于模拟实际环境中的障碍物分布情况以及可行走区域。 #### 时间限制说明 每个案例会提供三个参数 N、M 和 T 来定义地图尺寸及时间上限。这里需要注意的是,在规定的时间内完成任务至关重要,因为一旦超时则视为失败。 #### 实现思路概述 采用DFS算法遍历整个迷宫空间寻找可行路线直至到达目标点。“深搜”的核心在于递归地探索每一个可能的方向直到遇到边界条件为止——即找到了出路或是确认当前路径不通而回溯至上一步继续尝试其他方向。 以下是基于上述分析的一个简单C++代码框架用来解决问题: ```cpp #include <iostream> using namespace std; const int MAX_N = 8; char maze[MAX_N][MAX_N]; bool visited[MAX_N][MAX_N]; int n, m, t; // 定义全局变量存储迷宫大小和最大允许步数 pair<int,int> start,end_; // 方向数组dx[]dy[],方便后续四个方位(x±1,y),(x,y±1)扩展节点. static const int dx[]={-1,+1,0 ,0}; static const int dy[]={0 ,0 ,-1,+1}; void dfs(pair<int,int> pos,int step){ if(step>t || !inBound(pos.first,pos.second))return ; // 越界或超过最长时间返回 if(maze[pos.first][pos.second]=='D'){cout<<"yes";exit(0);} // 找到了出口就结束程序并输出结果 for(int i=0;i<4;++i){ // 尝试上下左右四个方向前进 pair<int,int> next_pos={pos.first+dx[i],pos.second+dy[i]}; if(!visited[next_pos.first][next_pos.second]){ visited[next_pos.first][next_pos.second]=true; dfs(next_pos,step+1); visited[next_pos.first][next_pos.second]=false;// 回退状态以便下次访问 } } } int main(){ while(cin>>n>>m>>t&&(n||m||t)){ fill(&maze[0][0],&maze[n][m],' ');memset(visited,false,sizeof(bool)*n*m); char ch; bool flag=false; for(int i=0;i<n&&cin.get(ch);++i){ for(int j=0;j<m&&ch!='\n';j++,cin.get(ch)) switch(ch){ case 'S':start={i,j};break; case 'D':end_={i,j};break; default:maze[i][j]=ch;break; } cin.ignore(); } visited[start.first][start.second]=true; dfs(start,0); cout << "no\n"; } } ``` 这段代码实现了基本的功能需求,但为了提高效率还可以考虑剪枝优化等策略减少不必要的计算量。
评论 59
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值