迷宫问题Maze (BFS) 广度优先遍历 C语言

迷宫问题Maze




题目内容:

給你一個迷宮,

S為起點,E為終點。

請你找出走出迷宮所需要花費的最短步數。

你只能往上下左右四個方向移動。


输入格式:


第一行有一個數字T,代表有T組測資。

每組測資的第一行有兩個數字R、C,

代表迷宮的大小(R x C)。

接下來R行,每行有C個字元來描述迷宮,

'.'代表可以行走的路,

'X'代表不可行走的牆壁,

'S'代表起點,

'E'代表終點。

測資範圍:

T < 100

2 < R,C <= 30


输出要求:



對於每組測資,計算由起點到達終點的最少步數。

測資保證一定存在至少一條由起點通往終點的路徑。

將每組測資的步數加總後再輸出。


输入样例:

2

5 5

SXXXX

...XX

.X...

..XXX

....E

6 6

......

.S..X.

XXX...

....X.

.X..XX

.EX...


输出样例:

18


时间限制:500ms内存限制:32000kb

代码:

#include <stdio.h>
#include <stdlib.h>
#define R 30
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
struct _node{
	int level;
	int x;
	int y;
	struct _node* next;
};

typedef struct _node Node;

struct _queue{
	Node* head;
	Node* tail;
	int size;
};

typedef struct _queue Queue;

void enQueue(Queue* que, int x,int y, int level)
{
	Node* p;
	p = (Node*)malloc(sizeof(Node));
	p->x = x;
	p->y = y;
	p->level = level;
	p->next = NULL;
	if(que->size==0)
	{
		que->head = p;
		que->tail = p;
	}
	else
	{
		que->tail->next=p;
		que->tail = p;
	}
	que->size+=1;
}


int short_path(char* array, int start_x, int start_y, int row, int col)
{
	Node *head,*tail,*p,*target;
	int x,y, level,i,j;
	char chr;
	int flag[row][col];
	for(i=0;i<row;i++)
	{
		for(j=0;j<col;j++)
		{
			flag[i][j]=0;
		}
	}
	flag[start_x][start_y]=1;
	Queue que;
	que.head = NULL;
	que.tail = NULL;
	que.size = 0;
	enQueue(&que, start_x, start_y, 0);
	while(que.size>0)
	{
		//deqQueue
		target = que.head;
		x = target->x;
		y = target->y;
		level = target->level;
		que.head = target->next;
		que.size -= 1;
		//chr = *(array+x*col+y);
		//printf("deQueue x= %d, y= %d, level= %d\n",x,y,level);
		free(target);
		// left
		if((y-1>=0) && (y<col) && (flag[x][y-1]==0))
		{
			chr = *(array+x*col+y-1);
			//printf("explored left %c, x= %d, y= %d, level= %d\n", chr, x,y-1, level+1);
			flag[x][y-1]=1;
			if(chr=='.')
			{
				//printf("enqueue x= %d, y= %d, level= %d\n",x,y-1,level+1);
				enQueue(&que, x,y-1,level+1);
			}
			else
			if(chr=='E') return level+1;
		}
		// right
		if((y+1<col) && (y>=0) && (flag[x][y+1]==0))
		{
			chr = *(array+x*col+y+1);
			//printf("explored right %c, x= %d, y= %d, level= %d\n", chr, x,y+1, level+1);
			flag[x][y+1]=1;
			if(chr=='.')
			{
				//printf("enqueue x= %d, y= %d, level= %d\n",x,y+1,level+1);
				enQueue(&que, x,y+1,level+1);
			}
			else
			if(chr=='E') return level+1;
		}
		// up 
		if(x-1>=0 && x<row && (flag[x-1][y]==0))
		{
			chr = *(array+(x-1)*col+y);
			//printf("explored up %c, x= %d, y= %d, level= %d\n", chr, x-1,y, level+1);
		    flag[x-1][y]=1;
			if(chr=='.')
			{
				//printf("enqueue x= %d, y= %d, level= %d\n",x-1,y,level+1);
				enQueue(&que, x-1,y,level+1);
			}
			else
			if(chr=='E') return level+1;
		}
		// down
		if(x+1<row && x>=0 && (flag[x+1][y]==0))
		{
			chr = *(array+(x+1)*col+y);
			//printf("explored down %c, x= %d, y= %d, level= %d\n", chr, x+1,y, level+1);
			flag[x+1][y]=1;
			if(chr=='.')
			{
				//printf("enqueue x= %d, y= %d, level= %d\n",x+1,y,level+1);
				enQueue(&que, x+1,y,level+1);
			}
			else
			if(chr=='E') return level+1;
		}
	}
	return -1;
}
int main() {
	int m,n,i,j,strt_x,strt_y,test_num,k,sum=0;
	scanf("%d",&test_num);
	for(k=0;k<test_num;k++)
	{
		scanf("%d %d\n",&m,&n);
		char array[m][n];
		for(i=0;i<m;i++)
		{
			gets(array[i]);
			for(j=0;j<n;j++)
			{
				if(array[i][j]=='S')
				{
					strt_x=i;
					strt_y=j;
				}
			}
	    }
	    sum += short_path((char*)array, strt_x, strt_y, m, n);
	}
	
	/*
	array[0][0]='.';array[0][1]='.'; array[0][2]='.';array[0][3]='.';array[0][4]='.';array[0][5]='.';
    array[1][0]='.';array[1][1]='S'; array[1][2]='.';array[1][3]='.';array[1][4]='X';array[1][5]='.';
    array[2][0]='X';array[2][1]='X'; array[2][2]='X';array[2][3]='.';array[2][4]='.';array[2][5]='.';
	array[3][0]='.';array[3][1]='.'; array[3][2]='.';array[3][3]='.';array[3][4]='X';array[3][5]='.';
	array[4][0]='.';array[4][1]='X'; array[4][2]='.';array[4][3]='.';array[4][4]='X';array[4][5]='X';
	array[5][0]='.';array[5][1]='E'; array[5][2]='X';array[5][3]='.';array[5][4]='.';array[5][5]='.';
	strt_x = 1;
	strt_y = 1;
    */
	/*
	
	*/
	//
	//printf("x: %d, y= %d\n", strt_x, strt_y);
	
	printf("%d",sum);
	
	/*
	for(i=0;i<m;i++)
	{
		printf("%c %c %c %c %c\n",array[i][0],array[i][1],array[i][2],array[i][3],array[i][4]);
	}*/
	return 0;
}



  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用 C 语言实现广度优先遍历迷宫问题并输出线路的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define ROW 5 // 迷宫行数 #define COL 5 // 迷宫列数 typedef struct { int row; int col; } Point; // 表示迷宫中的一个点 typedef struct { Point point; int step; } Node; // 表示 BFS 中的一个节点 Point start = {0, 0}; // 起点 Point end = {4, 4}; // 终点 int maze[ROW][COL] = { // 迷宫地图,0 表示可通过,1 表示障碍物 {0, 1, 0, 0, 0}, {0, 1, 0, 1, 0}, {0, 1, 0, 1, 0}, {0, 1, 0, 1, 0}, {0, 0, 0, 1, 0}, }; Point prev[ROW][COL]; // 记录每个节点的前驱节点,用于输出路径 bool visited[ROW][COL]; // 标记每个节点是否被访问过 Node queue[ROW * COL]; // 队列,存储 BFS 中待访问的节点 int front = 0; // 队列头指针 int rear = 0; // 队列尾指针 // 判断点是否在迷宫内且可通过 bool isValid(Point point) { if (point.row < 0 || point.row >= ROW || point.col < 0 || point.col >= COL) return false; if (maze[point.row][point.col] == 1) return false; return true; } // BFS 遍历迷宫 void bfs() { // 初始化起点 visited[start.row][start.col] = true; queue[rear++] = (Node){start, 0}; // BFS 遍历 while (front < rear) { Node curr = queue[front++]; // 取出队首节点 Point currPoint = curr.point; // 当前节点的位置 if (currPoint.row == end.row && currPoint.col == end.col) { // 找到终点,退出 return; } // 遍历当前节点的四个相邻节点 Point nextPoints[4] = { {currPoint.row - 1, currPoint.col}, {currPoint.row, currPoint.col + 1}, {currPoint.row + 1, currPoint.col}, {currPoint.row, currPoint.col - 1}, }; for (int i = 0; i < 4; i++) { Point nextPoint = nextPoints[i]; if (isValid(nextPoint) && !visited[nextPoint.row][nextPoint.col]) { // 如果相邻节点可通过且未被访问过,加入队列 visited[nextPoint.row][nextPoint.col] = true; queue[rear++] = (Node){nextPoint, curr.step + 1}; prev[nextPoint.row][nextPoint.col] = currPoint; } } } } // 输出路径 void printPath() { Point curr = end; while (curr.row != start.row || curr.col != start.col) { printf("(%d, %d) -> ", curr.row, curr.col); curr = prev[curr.row][curr.col]; } printf("(%d, %d)\n", start.row, start.col); } int main() { bfs(); printPath(); return 0; } ``` 该代码使用 BFS 遍历迷宫,并记录每个节点的前驱节点,用于输出路径。首先定义了 `Point` 和 `Node` 结构体来表示迷宫中的点和 BFS 遍历中的节点,定义了起点和终点、迷宫地图、前驱节点数组和 visited 数组等变量。然后实现了 `isValid()` 函数用于判断一个点是否在迷宫内且可通过,以及 `bfs()` 函数用于 BFS 遍历迷宫。在 `bfs()` 函数中,用队列存储待访问的节点,每次取出队首节点并遍历其四个相邻节点,如果相邻节点可通过且未被访问过,就加入队列,并记录其前驱节点。当找到终点时,就退出 BFS 遍历。最后实现了 `printPath()` 函数用于输出路径。该代码的时间复杂度为 $O(mn)$,其中 $m$ 和 $n$ 分别为迷宫的行数和列数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值