티스토리 뷰

1.문제 링크

https://www.acmicpc.net/problem/1981

 

1981번: 배열에서 이동

문제 n×n짜리의 배열이 하나 있다. 이 배열의 (1, 1)에서 (n, n)까지 이동하려고 한다. 이동할 때는 상, 하, 좌, 우의 네 인접한 칸으로만 이동할 수 있다. 이와 같이 이동하다 보면, 배열에서 몇 개의 수를 거쳐서 이동하게 된다. 이동하기 위해 거쳐 간 수들 중 최댓값과 최솟값의 차이가 가장 작아지는 경우를 구하는 프로그램을 작성하시오. 입력 첫째 줄에 n(2≤n≤100)이 주어진다. 다음 n개의 줄에는 배열이 주어진다. 배열의 각 수는 0보

www.acmicpc.net

 

2.소스 코드

BFS + 이분탐색 문제

#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;

const int dx[] = { 1,-1,0,0 };
const int dy[] = { 0,0,1,-1 };

int map[101][101];
int start;
int endval;
int n;
int maxval = -987654321;
int minval = 987654321;

struct COORD {
	int y, x;
};

bool bfs(int mid)
{
	queue<COORD> q;
	//mid과 같거나 작게 탐색이 가능한지,
	for(int k=minval; k <=maxval;k++)
	{
		bool visited[101][101] = { false, };

		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				visited[i][j] = true;

		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++) {
				//최소값을 k로 두겠다.
				if (map[i][j] >= k && map[i][j] - k <= mid)
					visited[i][j] = false;
			}
				COORD begin;
				begin.y = 1, begin.x = 1;

				if (visited[begin.y][begin.x])
					continue;
				else
				{
					q.push(begin);
					visited[begin.y][begin.x] = true;
				}
				while (!q.empty())
				{
					COORD cur = q.front(); q.pop();

					if (cur.x == n && cur.y == n)
						return true;

					for (int dir = 0; dir < 4; dir++)
					{
						COORD next;
						next.y = cur.y + dy[dir];
						next.x = cur.x + dx[dir];

						//맵 벗어나면 취소
						if (next.x < 1 || next.y < 1 || next.x > n || next.y > n)
							continue;

						if (visited[next.y][next.x] == false)
						{
							q.push(next);
							visited[next.y][next.x] = true;
						}

					}
				}
			}
	return false;
}

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

	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++){
			scanf("%d", &map[i][j]);
			maxval = max(map[i][j], maxval);
			minval = min(map[i][j], minval);
		}
	start = 0;
	endval = maxval - minval;

	int ret = 0;

	while (start <= endval)
	{
		bool isok = false;
		int mid = (start + endval) / 2;

		//탐색이 성공하면,
		isok = bfs(mid);
		//값을 기억하고 한번 낮춰보기..
		if (isok)
		{
			ret = mid;
			endval = mid - 1;
		}
		else
		{
			start = mid + 1;
		}
	}

	printf("%d", ret);


	return 0;
}
댓글
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Total
Today
Yesterday