공부/PS (백준)

[BOJ] 17086 아기 상어 2 / C++

happyst 2022. 3. 29. 23:14

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

 

17086번: 아기 상어 2

첫째 줄에 공간의 크기 N과 M(2 ≤ N, M ≤ 50)이 주어진다. 둘째 줄부터 N개의 줄에 공간의 상태가 주어지며, 0은 빈 칸, 1은 아기 상어가 있는 칸이다. 빈 칸의 개수가 한 개 이상인 입력만 주어진다.

www.acmicpc.net

 

#include <stdio.h>
#include <vector>
#include <queue>

using namespace std;

int N, M; // 2 <= N, M <= 50
int map[60][60]; // 0: 빈칸, 1: 아기 상어
int visited[60][60];

int dr[8] = { -1,-1,-1,0,1,1,1,0 };
int dc[8] = { -1,0,1,1,1,0,-1,-1 };

struct st {
	int r, c, t;
};

queue <st> q;
vector <pair<int, int> >blank_spot;
int answer = 0;

void clear_visited()
{
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < M; j++)
		{
			visited[i][j] = 0;
		}
	}
}

void input()
{
	scanf("%d %d", &N, &M);
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < M; j++)
		{
			scanf("%1d", &map[i][j]);
			if (map[i][j] == 0) blank_spot.push_back(make_pair(i, j));
		}
	}
}

int getDistance(int r, int c)
{
	if (!visited[r][c])
	{
		visited[r][c] = 1;
	}
	q.push({ r,c,0 });

	while (!q.empty())
	{
		struct st data = q.front();
		int cur_r = data.r;
		int cur_c = data.c;
		int cur_t = data.t;
		q.pop();
		if (map[cur_r][cur_c] == 1) return cur_t;

		for (int k = 0; k < 8; k++)
		{
			int nr = cur_r + dr[k];
			int nc = cur_c + dc[k];

			if (nr < 0 || nr >= N || nc < 0 || nc >= M || visited[nr][nc]) continue;
			visited[nr][nc] = 1;
			q.push({ nr,nc, cur_t + 1 });
		}
	}
	return 0;
}

void solve()
{
	for (int i = 0; i < blank_spot.size(); i++)
	{
		clear_visited();
		int r = blank_spot[i].first;
		int c = blank_spot[i].second;

		int dist = getDistance(r, c);
		while (!q.empty()) q.pop();
		//printf("[%d] dist = %d, size = %d\n", i, dist, q.size());
		if (dist > answer) answer = dist;
	}
}

int main(void)
{
	input();
	solve();
	printf("%d\n", answer);
	return 0;
}

 

문제를 잘 읽자!!

 

1. N x M의 입력을 받으며 빈 칸의 좌표들을 vector에 저장함

2. vector의 각 원소에 대해 BFS를 이용하여 이동한 칸을 세고, 이동한 칸의 최소값을 얻기 위해서 아기상어를 만나면 그때까지 이동한 칸의 값을 return 한다.