import java.util.*;
class Solution {
int Rsize,Csize,Rgoal,Cgoal,count;
boolean find=false;
String answer="impossible";
public String solution(int n, int m, int x, int y, int r, int c, int k) {
Rsize=n;
Csize=m;
Rgoal=r-1;
Cgoal=c-1;
count=k;
dfs(x-1,y-1,"");
return answer;
}
public void dfs(int r,int c,String str){
if(find) return;
int distance=Math.abs(r-Rgoal)+Math.abs(c-Cgoal);
if(distance>count-str.length()||(count-str.length()-distance)%2!=0) return;
if(str.length()==count){
find=true;
if(r==Rgoal&&c==Cgoal) answer=str;
return;
}
if(r<Rsize-1){
String newStr=str+"d";
dfs(r+1,c,newStr);
}
if(c>0){
String newStr=str+"l";
dfs(r,c-1,newStr);
}
if(c<Csize-1){
String newStr=str+"r";
dfs(r,c+1,newStr);
}
if(r>0){
String newStr=str+"u";
dfs(r-1,c,newStr);
}
}
}
최적화가 필요한 dfs문제이다. 그냥 dfs로만 풀면 시간초과가 난다.
일단 이 문제는 찾은 답 중에서 사전 순으로 가장 빠른 답을 구하는 문제이다.
하지만, 모든 답을 찾고 정렬을 해버리면 시간초과가 난다.
그래서 탐색 자체를 d(하)-l(좌)-r(우)-u(상) 순서대로 하면, 가장 먼저 도착한 답이 사전 상 가장 빠른 문자열이 되므로 정답이 된다.
(1) 먼저, 시작 지점으로부터 dfs탐색을 시작한다.
(2) dfs 함수에서는 다음을 실행한다.
(3) 가장 먼저 찾은 답이 정답이므로, 한번 답을 찾으면 다른 탐색들은 find=true가 되어 종료된다. 그렇기 때문에, 그냥 answer을 return 해주면 된다.
처음엔 그냥 dfs 탐색으로 풀면 되겠다 싶어서 풀었더니, 시간초과가 났다.
그리고 어떻게 탐색 횟수를 줄여야 할 지 도저히 생각이 안나서 다른사람 풀이를 참고했다.
거리와 남은 이동횟수를 계산한 후, 도달할 수 없는 경우들을 가지치기 했는데도 또다시 시간초과가 났다.
모든 답을 찾는 방식이 문제였다.
모든 답을 찾아 사전 순으로 정렬하는 것이 아닌 사전 순으로 탐색을 해서 가장 먼저 찾은 답을 정답으로 하는 방식을 사용해야 했다.
풀만 한 것 같으면서도 어려운 문제였다. 사전 순으로 상하좌우를 탐색한다는 생각을 하기가 어려웠다.
카카오 문제라 그런지 퀄리티가 좋은듯 하다.
출처 : 프로그래머스 코딩 테스트 연습 https://school.programmers.co.kr/learn/challenges