BOJ 2178-迷宫を探す


寻找迷宫(2178)


完全なコード

#include <stdio.h>
#include <stdlib.h>

int	**maze, **flag;

typedef struct	_node
{
	int		x, y, cnt;
	struct _node	*next;
}		node;

node	*front, *rear;

void	init_queue(void)
{
	front = (node *)malloc(sizeof(node));
	rear = (node *)malloc(sizeof(node));

	front -> next = rear;
	rear -> next = rear;
}

void	push(int x, int y, int cnt)
{
	node	*new;

	new = (node *)malloc(sizeof(node));
	new -> x = x;
	new -> y = y;
	new -> cnt = cnt;
	if (front -> next == rear)
	{
		front -> next = new;
		new -> next = rear;
		rear -> next = new;
		return ;
	}
	rear -> next -> next = new;
	new -> next = rear;
	rear -> next = new;
}

void	pop(void)
{
	node	*curr;

	curr = front -> next;
	front -> next = curr -> next;
	free(curr);
}

int	BFS(int N, int M)
{
	int cnt = 0;
	push(1 ,1, cnt + 1);
	flag[1][1]++;
	while (front -> next != rear)
	{
		int	buf_x, buf_y;

		buf_x = front -> next -> x;
		buf_y = front -> next -> y;
		cnt = front -> next -> cnt;
		pop();
		if (buf_x == M && buf_y == N)
			break ;
		if (buf_x - 1 >= 1 && !flag[buf_y][buf_x - 1] && maze[buf_y][buf_x - 1])
		{
			push(buf_x - 1, buf_y, cnt + 1);
			flag[buf_y][buf_x - 1]++;
		}
		if (buf_x + 1 <= M && !flag[buf_y][buf_x +1] && maze[buf_y][buf_x + 1])
		{
			push(buf_x + 1, buf_y, cnt + 1);
			flag[buf_y][buf_x + 1]++;
		}
		if (buf_y - 1 >= 1 && !flag[buf_y - 1][buf_x] && maze[buf_y - 1][buf_x])
		{
			push(buf_x, buf_y - 1, cnt + 1);
			flag[buf_y - 1][buf_x]++;
		}
		if (buf_y + 1 <= N && !flag[buf_y + 1][buf_x] && maze[buf_y + 1][buf_x])
		{
			push(buf_x, buf_y + 1, cnt + 1);
			flag[buf_y + 1][buf_x]++;
		}
	}
	return (cnt);
}

int	main(void)
{
	int	M, N;

	init_queue();
	scanf("%d%d", &N, &M);
	maze = (int **)calloc(1, sizeof(int *) * (N + 1));
	flag = (int **)calloc(1, sizeof(int *) * (N + 1));
	for (int i = 0; i <= N; i++)
	{
		maze[i] = (int *)calloc(1, sizeof(int) * (M + 1));
		flag[i] = (int *)calloc(1, sizeof(int) * (M + 1));
	}
	for (int y = 1; y <= N; y++)
	{
		char	buf[101];
		scanf("%s", buf);
		for (int i = 0; i < M; i++)
			maze[y][i + 1] = buf[i] - '0';
	}
	printf("%d\n", BFS(N, M));
	for (int i = 0; i <= N; i++)
	{
		free(maze[i]);
		free(flag[i]);
	}
	free(maze);
	free(flag);
	free(front);
	free(rear);
	return (0);
}
Cを書いて、メモリを動的に割り当てて、このようにコードは汚くなりませんが、できるだけ毒性があるように書きます.ううう
typedef struct	_node
{
	int		x, y, cnt;
	struct _node	*next;
}		node;

Queueの構造


cnt変数があり、xとyの座標と目的地へのプローブ回数を含む.
配列の割り当ては1,1の座標からN,Mの配列であるため,各配列には1つのN+1と1つのM+1が割り当てられる.
int	BFS(int N, int M)
{
	int cnt = 0;
	push(1 ,1, cnt + 1);
	flag[1][1]++;
	while (front -> next != rear)
	{
		int	buf_x, buf_y;

		buf_x = front -> next -> x;
		buf_y = front -> next -> y;
		cnt = front -> next -> cnt;
		pop();
		if (buf_x == M && buf_y == N)
			break ;
		if (buf_x - 1 >= 1 && !flag[buf_y][buf_x - 1] && maze[buf_y][buf_x - 1])
		{
			push(buf_x - 1, buf_y, cnt + 1);
			flag[buf_y][buf_x - 1]++;
		}
		if (buf_x + 1 <= M && !flag[buf_y][buf_x +1] && maze[buf_y][buf_x + 1])
		{
			push(buf_x + 1, buf_y, cnt + 1);
			flag[buf_y][buf_x + 1]++;
		}
		if (buf_y - 1 >= 1 && !flag[buf_y - 1][buf_x] && maze[buf_y - 1][buf_x])
		{
			push(buf_x, buf_y - 1, cnt + 1);
			flag[buf_y - 1][buf_x]++;
		}
		if (buf_y + 1 <= N && !flag[buf_y + 1][buf_x] && maze[buf_y + 1][buf_x])
		{
			push(buf_x, buf_y + 1, cnt + 1);
			flag[buf_y + 1][buf_x]++;
		}
	}
	return (cnt);
}

終了条件


関数の終了条件は、キューが空の迷路に出口がないか、N、M座標(到達点)にアクセスしたときに終了することです.

アルゴリズム#アルゴリズム#


「ラビリンス検索」の論理は、開始値をキューに入れ、最初の値もアクセス数で計算するため、レコードがキューに1回アクセスしたことを示します.
次に、dequeueを使用して得られた値をバッファに入れ、バッファの上下左右に隣接する長さと、同時にアクセスしていないすべての値を+1の回数でキューに入れます.
このように到着ポイントにアクセスすると、重複文はアクセス回数で終了し、キュー内の最終(アクセス後)cnt値を返して終了します.