티스토리 뷰
해설
DFS를 사용하여 백트랙킹으로 접근하는 문제이다.
문제의 핵심 포인트는 2가지이다.
1. (남은 움직임 수) - (현재 위치에서 목표까지의 거리) 가 0보다 작으면 실패.
2. (남은 움직임 수) - (현재 위치에서 목표까지의 거리) 가 홀수번이면 실패.
이다.
최단 루트에서 한 칸을 이탈한 뒤 다시 이탈한 지점까지 돌아오는 거리는 +2 가 된다.
두 칸을 이탈하면 +4 가된다. 이는 무조건 (최단루트) + (K 값을 만족시키기 위한 추가이동) 에서 (K 값을 만족시키기 위한 추가이동) 은 짝수가 되어야 한다는 의미이다.
그 외에는 기존의 DFS와 동일하다.
4 방면으로 탐색해준 뒤 이동하는 위치와 걸맞게 d,r,l,u 을 문자열에 추가해주면 된다. 백트랙킹 문제이므로 DFS를 끝내고 나오면 빼주는것도 잊지 말자.
문제 설명
n x m 격자 미로가 주어집니다. 당신은 미로의 (x, y)에서 출발해 (r, c)로 이동해서 탈출해야 합니다.
단, 미로를 탈출하는 조건이 세 가지 있습니다.
- 격자의 바깥으로는 나갈 수 없습니다.
- (x, y)에서 (r, c)까지 이동하는 거리가 총 k여야 합니다. 이때, (x, y)와 (r, c)격자를 포함해, 같은 격자를 두 번 이상 방문해도 됩니다.
- 미로에서 탈출한 경로를 문자열로 나타냈을 때, 문자열이 사전 순으로 가장 빠른 경로로 탈출해야 합니다.
이동 경로는 다음과 같이 문자열로 바꿀 수 있습니다.
- l: 왼쪽으로 한 칸 이동
- r: 오른쪽으로 한 칸 이동
- u: 위쪽으로 한 칸 이동
- d: 아래쪽으로 한 칸 이동
예를 들어, 왼쪽으로 한 칸, 위로 한 칸, 왼쪽으로 한 칸 움직였다면, 문자열 "lul"로 나타낼 수 있습니다.
미로에서는 인접한 상, 하, 좌, 우 격자로 한 칸씩 이동할 수 있습니다.
예를 들어 다음과 같이 3 x 4 격자가 있다고 가정해 보겠습니다.
.... ..S. E...
미로의 좌측 상단은 (1, 1)이고 우측 하단은 (3, 4)입니다. .은 빈 공간, S는 출발 지점, E는 탈출 지점입니다.
탈출까지 이동해야 하는 거리 k가 5라면 다음과 같은 경로로 탈출할 수 있습니다.
- lldud
- ulldd
- rdlll
- dllrl
- dllud
- ...
이때 dllrl보다 사전 순으로 빠른 경로로 탈출할 수는 없습니다.
격자의 크기를 뜻하는 정수 n, m, 출발 위치를 뜻하는 정수 x, y, 탈출 지점을 뜻하는 정수 r, c, 탈출까지 이동해야 하는 거리를 뜻하는 정수 k가 매개변수로 주어집니다. 이때, 미로를 탈출하기 위한 경로를 return 하도록 solution 함수를 완성해주세요. 단, 위 조건대로 미로를 탈출할 수 없는 경우 "impossible"을 return 해야 합니다.
코드
#include <string>
#include <vector>
using namespace std;
string answer = "";
string RetAnswer= "impossible";
bool flag = false;
int defense[4][2] = {{1,0},{0,-1},{0,1},{-1,0}};
char words[4] = {'d','l','r','u'};
int N,M,X,Y,R,C,K;
int get_dist(int x,int y,int a,int b)
{
return abs(x-a) + abs(y-b);
}
void DFS(int count, int curX, int curY)
{
if(flag)
return;
int dist = get_dist(curX, curY, R,C);
if(K-count-dist < 0 )
return;
if((K-count-dist)%2 == 1)
return;
if(count == K)
{
if(curX==R && curY == C)
{
flag = true;
RetAnswer = answer;
}
return;
}
for(int k = 0 ;k < 4 ;k++)
{
int newx = curX + defense[k][0];
int newy = curY + defense[k][1];
if(newx > 0 && newx <= N && newy > 0 && newy <= M)
{
answer += words[k];
DFS(count + 1, newx, newy);
answer.pop_back();
}
}
}
string solution(int n, int m, int x, int y, int r, int c, int k) {
N = n;
M = m;
X = x;
Y = y;
R = r;
C = c;
K = k;
DFS(0,x,y);
return RetAnswer;
}
'공부 > 코딩테스트' 카테고리의 다른 글
[ 프로그래머스 C++ ] 혼자 놀기의 달인 lv2 (0) | 2023.09.04 |
---|---|
[ 프로그래머스 C++ ] 숫자 카드 나누기 lv2 (0) | 2023.09.01 |
[ 프로그래머스 C++ ] 연속된 부분 수열의 합 lv2 (0) | 2023.08.28 |
[ 프로그래머스 C++ ] 오픈채팅방 lv2 (0) | 2023.08.25 |
[ 프로그래머스 C++ ] 리코쳇 로봇 lv2 (0) | 2023.08.24 |
- Total
- Today
- Yesterday
- LV2
- sort
- 누적합
- 개인공부
- BFS
- 디자인 패턴
- LV3
- 프로그래머스
- 고득점 Kit
- 재귀
- Unreal 5.1
- Ue
- Heap
- level3
- FPS
- IMGUI
- 해시
- 탐욕법
- 완전탐색
- greedy
- UE5
- 너비우선탐색
- 고득점kit
- 채팅서버
- 스택/큐
- 데디케이티드
- C++
- 정렬
- 힙
- DFS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |