迷宮問題


7-9 求解迷宮從入口到出口的路徑 (15分)

求解迷宮從入口到出口的路徑。輸入一個迷宮,求從入口通向出口的可行路徑。為簡化問題,迷宮用二維數組 int maze[10][10]來存儲障礙物的分布,假設迷宮的橫向和縱向尺寸的大小是一樣的,並由程序運行讀入, 若讀入迷宮大小的值是n(3<n<=10),則該迷宮橫向或縱向尺寸都是n,規定迷宮最外面的一圈是障礙物,迷宮的入口是maze[1][1],出口是maze[n-2][n-2], 若maze[i][j] = 1代表該位置是障礙物,若maze[i][j] = 0代表該位置是可以行走的空位(0<=i<=n-1, 0<=j<=n-1)。求從入口maze[1][1]到出口maze[n-2][n-2]可以走通的路徑。要求迷宮中只允許在水平或上下四個方向的空位上行走,走過的位置不能重復走,規定必須按向右、向下、向左、向上的順序向前搜索試探。 如下這樣一個迷宮:

對應的二維數組表示:
int maze[10][10]={ {1,1,1,1,1,1,1,1,1,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,0,0,1,1,0,0,1}, {1,0,1,1,1,0,0,0,1,1}, {1,0,0,0,1,0,0,0,1,1}, {1,0,1,0,0,0,1,0,0,1}, {1,1,1,1,0,1,1,0,1,1}, {1,0,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1}};

輸入格式:
輸入迷宮大小的整數n, 以及n行和n列的二維數組(數組元素1代表障礙物,0代表空位)。

輸出格式:
依次輸出從入口到出口可行路徑每個位置的行列下標(i,j),每個位置間用“,”分隔。若沒有通路,輸出:NO。

輸入樣例1:

4
1 1 1 1
1 0 1 1
1 0 0 1
1 1 1 1

輸出樣例1:

(1,1)(2,1)(2,2)

輸入樣例2:

10
1 1 1 1 1 1 1 1 1 1
1 0 0 1 0 0 0 1 0 1
1 0 0 1 0 0 0 1 0 1
1 0 0 0 0 1 1 0 0 1
1 0 1 1 1 0 0 0 0 1
1 0 0 0 1 0 0 0 0 1
1 0 1 0 0 0 1 0 0 1
1 0 1 1 1 0 1 1 0 1
1 1 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1

輸出樣例2:

(1,1)(1,2)(2,2)(3,2)(3,1)(4,1)(5,1)(5,2)(5,3)(6,3)(6,4)(6,5)(7,5)(8,5)(8,6)(8,7)(8,8)

實驗代碼(棧)

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MaxSize 100

typedef struct
{
	int i, j;
	int di;
}Box;

typedef struct
{
	Box data[MaxSize];
	int top;
}StType;

int maze[MaxSize][MaxSize];  //迷宮數組

void InitStack(StType*& s)  //初始化棧
{
	s = (StType*)malloc(sizeof(StType));
	s->top = -1;
}

void DestroyStack(StType*& s)  //銷毀棧
{
	free(s);
}

bool StackEmpty(StType* s)  //判斷棧是否為空
{
	return (s->top == -1);
}

bool Push(StType*& s, Box e)  //進棧
{
	if (s->top == MaxSize - 1)
		return false;
	s->top++;
	s->data[s->top] = e;
	return true;
}

bool Pop(StType*& s, Box& e)  //出棧
{
	if (s->top == -1)
		return false;
	e = s->data[s->top];
	s->top--;
	return true;
}

bool GetTop(StType*& s, Box& e)  //取棧頂元素
{
	if (s->top == -1)
		return false;

	e = s->data[s->top];
	return true;
}

bool mgpath(int xi, int yi, int xe, int ye)  //迷宮算法
{
	Box path[MaxSize], e;
	int i, j, di, i1, j1, k;
	bool find;
	StType* st;

	InitStack(st);
	e.i = xi; 
	e.j = yi;
	e.di = -1;

	Push(st, e);
	maze[xi][yi] = -1;

	while (!StackEmpty(st))
	{
		GetTop(st, e);
		i = e.i;
		j = e.j;
		di = e.di;
		if (i == xe && j == ye)  //找到出口
		{
			k = 0;

			while (!StackEmpty(st))
			{
				Pop(st, e);
				path[k++] = e;
			}

			while (k >= 1)
			{
				k--;
				printf("(%d,%d)", path[k].i, path[k].j);
			}

			DestroyStack(st);
			return true;
		}

		find = false;
		while (di < 4 && !find)
		{
			di++;
			switch (di)
			{
			case 0:i1 = i; j1 = j + 1; break;  //向右
			case 1:i1 = i + 1; j1 = j; break;  //向下
			case 2:i1 = i; j1 = j - 1; break;  //向左
			case 3:i1 = i - 1; j1 = j; break;  //向上
			}

			if (maze[i1][j1] == 0)
			{
				find = true;
			}
		}
		if (find)
		{
			st->data[st->top].di = di;
			e.i = i1;
			e.j = j1;
			e.di = -1;
			Push(st, e);
			maze[i1][j1] = -1;
		}
		else
		{
			Pop(st, e);
			maze[e.i][e, j] = 0;
		}
	}
	DestroyStack(st);
	return false;
}

int main()
{
	int n;
	scanf("%d", &n);

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			scanf("%d", &maze[i][j]);
		}
	}

	if (!mgpath(1, 1, n-2, n-2))
		printf("NO\n");

	return 0;
}

實驗代碼(隊列)

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MaxSize 100

typedef struct
{
	int i, j;
	int pre;
}Box;

typedef struct
{
	Box data[MaxSize];
	int front, rear;
}QuType;

int maze[MaxSize][MaxSize];

void InitQueue(QuType*& q)  //初始化隊列
{
	q = (QuType*)malloc(sizeof(QuType));
	q->front = q->rear = -1;
}

void DestroyQueue(QuType*& q)  //銷毀隊列
{
	free(q);
}

bool QueueEmpty(QuType* q)  //判斷隊列是否為空
{
	return (q->front == q->rear);
}

bool enQueue(QuType*& q, Box e)  //進隊列
{
	if (q->rear == MaxSize - 1)
		return false;
	q->rear++;
	q->data[q->rear] = e;
	return true;
}

bool deQueue(QuType*& q, Box& e)  //出隊列
{
	if (q->front == q->rear)
		return false;
	q->front++;
	e = q->data[q->front];
	return true;
}
void print(QuType* qu, int front)  //從隊列qu中輸出迷宮路徑
{
	int k = front, j;

	do
	{
		j = k;
		k = qu->data[k].pre;
		qu->data[j].pre = -1;
	} while (k != 0);


	k = 0;
	while (k < MaxSize)
	{
		if (qu->data[k].pre == -1)
		{
			printf("(%d,%d)", qu->data[k].i, qu->data[k].j);
		}
		k++;
	}
}

bool mgpath(int xi, int yi, int xe, int ye)  //迷宮算法
{
	Box e;
	int i, j, di, i1, j1;
	QuType* qu;

	InitQueue(qu);
	e.i = xi;
	e.j = yi;
	e.pre = -1;

	enQueue(qu, e);
	maze[xi][yi] = -1;

	while (!QueueEmpty(qu))
	{
		deQueue(qu, e);
		i = e.i;
		j = e.j;
		if (i == xe && j == ye)
		{
			print(qu, qu->front);
			DestroyQueue(qu);
			return true;
		}

		for (di = 0; di < 4; di++)
		{
			switch (di)
			{
			case 0:i1 = i - 1; j1 = j; break;
			case 1:i1 = i; j1 = j + 1; break;
			case 2:i1 = i + 1; j1 = j; break;
			case 3:i1 = i; j1 = j - 1; break;
			}

			if (maze[i1][j1] == 0)
			{
				e.i = i1;
				e.j = j1;
				e.pre = qu->front;
				enQueue(qu, e);
				maze[i1][j1] = -1;
			}
		}
	}
	DestroyQueue(qu);
	return false;
}

int main()
{
	int n;
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			scanf("%d", &maze[i][j]);
		}
	}

	if (!mgpath(1, 1, n - 2, n - 2))
		printf("NO\n");

	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM