방문한 칸의 최소 높이가 x일 때 메일을 모두 보낼수 있는 방문한 칸의 최대 고도의 최솟값을 f(x)라 하자.
f(x)는 단조증가 함수가 된다. 고로 l=x, r=f(x)로 잡고 inchworm 알고리즘을 적용할 수 있다.
[l,r] 구간의 고도에 해당하는 칸만을 방문하여 모든 메일을 배달할 수 있다면 l++, 그렇지 않다면 r++을 해주며 모든 x에 대한 f(x) 값을 구한다. 답은 이러한 f(x) - x 들 중 최솟값이 된다.
시간복잡도는 $O(n^4)$
#include<cstdio> #include<algorithm> using namespace std; const int dx[] = { 0,1,0,-1,1,1,-1,-1 }, dy[] = { 1,0,-1,0,1,-1,1,-1 }; int n, a[50][50], vis[50][50], sx, sy, res = 1e9, v[2500], l, r; char s[50][51]; void f(int x, int y) { if (x < 0 || y < 0 || x == n || y == n || vis[x][y] || a[x][y]<v[l] || a[x][y]>v[r]) return; vis[x][y] = 1; for (int i = 0; i < 8; i++) f(x + dx[i], y + dy[i]); } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%s", s[i]); for (int j = 0; j < n; j++) if (s[i][j] == 'P') sx = i, sy = j; } for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) scanf("%d", a[i] + j), v[i*n + j] = a[i][j]; sort(v, v + n*n); while (r < n*n) { f(sx, sy); int flag = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (!vis[i][j] && s[i][j] == 'K') flag = 1; vis[i][j] = 0; } } flag ? r++ : res = min(res, v[r] - v[l++]); } printf("%d", res); return 0; }
댓글 없음 :
댓글 쓰기