알고리즘 문제풀이/백준

[백준/BOJ] 2589번 보물섬

노력의천재 2022. 5. 5. 02:05

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

 

2589번: 보물섬

첫째 줄에는 보물 지도의 세로의 크기와 가로의 크기가 빈칸을 사이에 두고 주어진다. 이어 L과 W로 표시된 보물 지도가 아래의 예와 같이 주어지며, 각 문자 사이에는 빈 칸이 없다. 보물 지도의

www.acmicpc.net

처음엔 다음과 같이 접근하였다.

 

1. 지도에서 2개의 육지를 뽑는 모든 조합을 구한다.

2. 조합에서 두 육지 사이의 거리가 가장 긴 경우를 DFS로 구한다.

3. DFS에서 선택된 2개의 육지 사이에 도달하는 최단 시간을 BFS로 구한다.

 

그러나 위와 같은 방법으로 문제를 접근하면 250C2 * 50 * 50 * 4 = 311,250,000로 시간초과 발생 (멍청하게 50C2로 계산해서 망했다 ㅋ)

 

따라서 복잡하게 생각할 필요없이, 2중 for문을 돌리며 육지를 만날때마다 BFS를 통해 모든 육지로의 거리를 구하고, 이 중에서 최대값을 구하면 된다.

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

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

int t, n, m, k, x, y, answer;
char area[51][51]; 
int visited[51][51];

int BFS(int sx, int sy) {
	int res = 0;
	memset(visited, -1, sizeof(visited));
	queue<pair<int, int>> q;
	q.push({ sx, sy });
	visited[sx][sy] = 0;
	
	while(!q.empty()) {
		tie(x, y) = q.front();
		q.pop();
		for(int i = 0; i < 4; i++) {
			int nx = x + dx[i];
			int ny = y + dy[i];
			if(nx < 0 || nx >= n || ny < 0 || ny >= m || area[nx][ny] == 'W' || visited[nx][ny] != -1) continue;
			q.push({ nx, ny });
			visited[nx][ny] = visited[x][y] + 1;
			res = max(res, visited[nx][ny]);
		}
	}
	
	return res;
}


int main() {
	//freopen("input.txt", "r", stdin);
	ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

	cin >> n >> m; 
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++) {
			cin >> area[i][j];
		}
	}

	for(int i = 0; i < n; i++) {
		for(int j = 0; j < m; j++) {
			if(area[i][j] == 'L') answer = max(answer, BFS(i, j));
		}
	}

	cout << answer;
}