풀이
parametric search로도 풀릴 것 같은데
나는 투포인터로 풀었다.
높이가 될 수 있는 후보는 1000000개이지만
주어지는 그리드의 크기가 50*50이 최대이므로 많아야 2500개 후보가 있을 수 있다.
주어진 높이들을 정렬한 다음, 투포인터로 구간을 잡아 dfs를 돌려주자.
코드
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int dx[] = { 0,0,-1,1,-1,-1,1,1 };
const int dy[] = { -1,1,0,0,-1,1,-1,1 };
int n, sx, sy, k, b[55][55], chk[55][55];
char a[55][55];
vector<int> v;
int dfs(int x, int y, int mn, int mx) {
if (chk[x][y] ||
b[x][y] < mn || mx < b[x][y] ||
x < 1 || n < x || y < 1 || n < y) {
return 0;
}
chk[x][y] = 1;
int ret = 0;
if (a[x][y] == 'K') {
ret++;
}
for (int i = 0; i < 8; i++) {
int nx = x+dx[i], ny = y+dy[i];
ret += dfs(nx, ny, mn, mx);
}
return ret;
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%s", a[i]+1);
for (int j = 1; j <= n; j++) {
if (a[i][j] == 'P') {
sx = i, sy = j;
}
if (a[i][j] == 'K') {
k++;
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
scanf("%d", &b[i][j]);
v.push_back(b[i][j]);
}
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
int i, j = 0, ans = 1e9;
for (i = 0; i < v.size(); i++) {
while (1) {
memset(chk, 0, sizeof(chk));
if (dfs(sx, sy, v[j], v[i]) != k) {
break;
}
ans = min(ans, v[i]-v[j]);
j++;
}
}
printf("%d", ans);
return 0;
}
아무말
백준, 백준 온라인 저지, BOJ, Baekjoon Online Judge, C, C++, 씨, 씨쁠쁠, JAVA, algorithm, 자바, 알고리즘, 자료구조, 문제, 문제 풀이, 풀이