난이도: level. 3
예상 태그: 백트래킹, dfs
소요 시간: 1h 30m
나는 저 중에 (i)의 경우를 생각하지 못했다....
import java.util.*;
class Solution {
static int sx, sy, ex, ey, len;
static int ln, lm;
static int[] dx = {1, 0, 0, -1};
static int[] dy = {0, -1, 1, 0};
static String[] di = {"d", "l", "r", "u"};
static String ans = null;
public String solution(int n, int m, int x, int y, int r, int c, int k) {
sx = x; sy = y; ex = r; ey = c; len = k;
ln = n; lm = m;
// 가능 불가능 판별
if((Math.abs(sx-ex) + Math.abs(sy-ey)) % 2 != k%2) {
return "impossible";
}
if((Math.abs(sx-ex) + Math.abs(sy-ey)) > k) return "impossible";
dfs(sx, sy, new StringBuffer(""));
return ans;
}
public static void dfs(int cx, int cy, StringBuffer s) {
// 가지치기 1
if(ans != null) return;
if(s.length() == len && cx == ex && cy == ey) {
ans = s.toString();
return;
} else if(s.length() == len) return;
// 가지치기 2
int dist = Math.abs(ex-cx) + Math.abs(ey-cy);
if(len - s.length() < dist) return;
for(int i=0; i<4; ++i) {
int nx = cx + dx[i], ny = cy + dy[i];
if(nx < 1 || nx > ln || ny < 1 || ny > lm) {
continue;
}
s.append(di[i]);
dfs(nx, ny, s);
s.delete(s.length()-1, s.length());
}
}
}
위 코드를 보면 dfs를 돌리기 전부터 출발-도착의 거리를 2로 나눈 나머지와 k를 2로 나눈 나머지를 비교하여 가능, 불가능을 판정할 수 있다.
dfs 안에서는
dfs로 풀릴까..? 싶었는데 가지치기를 잘 해야 dfs로 풀리는 문제였다.
나는 가지치기 1, 2를 생각해내지 못했다. 당연히 dy, dx를 잘 만들어놓았으므로, 가장 먼저 방문한 루트로 만들어진 문자열이 사전 순으로 가장 앞선다는 것, 현재 있는 곳에서의 거리가 k보다 크면 더 볼 필요 없다는것을 생각하지 못했다
백트랙킹을 다시 만나면 가지치기 조건들이 뭐가 있을지 꼼꼼하게 생각해 보아야겠다.