[백준] 15684 사다리 조작 풀이 Python, JavaOnlineJudge2021. 9. 22. 01:17
Table of Contents
반응형
접근방법
백트래킹
이미 문제에도 명시가 되어 있듯이 정답이 3보다 큰 값이거나 불가능한 경우에 -1을 출력합니다.
즉, 재귀함수의 depth에 제약을 걸어 가지치기를 할 수 있다는 말입니다.
저는 depth가 3에 도달하게 되면 더 이상 재귀 함수를 돌지 않게 설정했습니다.
로직
- 2차원 Array 형태로 사다리 Map을 그려준다
- 우측으로 이동하는 사다리는 1, 좌측으로 이동하는 사다리는 -1을 넣어준다. 내려가는 사다리는 0이다.
- 모든 설치 가능한 구역에 사다리를 설치하는 브루트포스 문제이다. 그렇기 때문에 모든 구간을 순회하는 DFS를 사용한다.
- 각 사다리 별로 번호에 맞게 내려오는지 확인한다.
- 만약 맞다면, 정답을 갱신한다
- 만약 틀리다면, 가로 사다리를 계속해서 설치한다.
- 각 사다리 별로 번호에 맞게 내려오는지 확인한다.
Python Code
N,M,H = map(int,input().split())
ladders = [[0]*N for _ in range(H)]
answer = -1
for i in range(M):
a,b = map(int,input().split())
ladders[a-1][b-1]=1
ladders[a-1][b]=-1
def checkLadders():
for ladder in range(N):
x = ladder
y = 0
moved = False
while y<H:
if ladders[y][x]==0 or moved:
y+=1
moved = False
elif ladders[y][x]==1 and not moved:
x+=1
moved = True
elif ladders[y][x]==-1 and not moved:
x-=1
moved = True
if x!=ladder:
return False
return True
def dfs(depth, number):
global answer
if checkLadders():
if answer==-1:answer = depth
else: answer = min(answer,depth)
return
if depth == 3:
return
for next_number in range(number,N*H):
x,y = next_number%N, next_number//N
if ladders[y][x]==0:
if x+1<N and ladders[y][x+1]==0:
ladders[y][x]=1
ladders[y][x+1]=-1
dfs(depth+1,next_number+1)
ladders[y][x]=0
ladders[y][x+1]=0
dfs(0,0)
print(answer)
Java Code
import java.util.*;
import java.io.*;
public class boj_15684_사다리조작 {
static StringBuilder sb = new StringBuilder();
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer st;
static int N,M,H,answer=-1;
static int[][] ladders;
static boolean checkLadders() {
for(int i =0;i<N;i++) {
int nx,ny;
nx = i;
ny = 0;
boolean moved = false;// 연속이동불가
while(ny<H) {
if(ladders[ny][nx]==0 || moved) {//하강
ny++;
moved = false;
}
else if(ladders[ny][nx]==1 && !moved) {//우측
nx++;
moved = true;
}
else if(ladders[ny][nx]==-1 && !moved) {//좌측
nx--;
moved = true;
}
}//끝에 도달
if(nx!=i) {//결과 값이 다름
return false;
}
}
return true;
}
static void solution(int depth,int number) {
if(checkLadders()) {
if(answer==-1)answer=depth;
else answer = Math.min(answer, depth);
return;
}
if(depth == 3) {
return;
}
for(int next_number = number;next_number<N*H;next_number++) {
int x = next_number%N;
int y = next_number/N;
if(ladders[y][x]==0) {
if(x+1<N&&ladders[y][x]==0&&ladders[y][x+1]==0) {//오른쪽 설치가능
ladders[y][x]=1;
ladders[y][x+1]=-1;
solution(depth+1,next_number+1);
ladders[y][x]=0;
ladders[y][x+1]=0;
}
}
}
}
static void input() throws IOException {
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken()); //사다리 갯수
M = Integer.parseInt(st.nextToken()); //가로선 갯수
H = Integer.parseInt(st.nextToken()); //높이
ladders = new int[H][N];
//0 하강, 1 오른쪽, -1 왼쪽
for(int i =0;i<M;i++) {
int a,b;
st = new StringTokenizer(br.readLine());
a = Integer.parseInt(st.nextToken())-1;
b = Integer.parseInt(st.nextToken())-1;
ladders[a][b] = 1;
ladders[a][b+1] = -1;
}
}
public static void main(String[] args) throws IOException {
input();
solution(0,0);
System.out.println(answer);
}
}
반응형
'OnlineJudge' 카테고리의 다른 글
[백준] 17825 주사위윷놀이 python 시간단축 풀이 (0) | 2021.10.04 |
---|---|
[백준] 2143 두 배열의 합 풀이 Python (0) | 2021.09.19 |
[백준] 2573 빙산 풀이 Python (0) | 2021.09.14 |
백준 1016 제곱ㄴㄴ수 풀이 Python (2) | 2021.06.24 |
[Codility] Lesson4 MaxCounters 풀이 Python (0) | 2021.06.22 |
@CODe_ :: 강승현입니다
인프런 지식공유자로 활동하고 있으며 MSA 전환이 취미입니다. 개발과 관련된 다양한 정보를 몰입감있게 전달합니다.