문제 링크
https://www.acmicpc.net/problem/15684
15684번: 사다리 조작
사다리 게임은 N개의 세로선과 M개의 가로선으로 이루어져 있다. 인접한 세로선 사이에는 가로선을 놓을 수 있는데, 각각의 세로선마다 가로선을 놓을 수 있는 위치의 개수는 H이고, 모든 세로선
www.acmicpc.net
풀이
두번째 푸는건데 ㅠㅠ 또 다른 블로그를 참고 하게 되는,, 세번째는 꼭 푼다.
백트래킹 문제이다.
헷갈리는 점은 H는 행, 모든 세로선(N)이 열이라는 것이다.
graph[H][N] 에 사다리를 표시한다.
1. graph[i][j] = 1 이란,
세로선 j 에서 j+1 사이에 가로 i번째에 가로선을 놓았다는 것이다.
2. dfs을 통해 가로선을 놓고, i에서 i로 가는 것이 가능한지 check() 함수로 확인한다.
1) dfs
- check()를 통해 가능하다면, 가로선을 놓은 횟수인 cnt를 갱신하고 return
- cnt 가 현재 최솟값인 ans보다 크거나 같거나, 3이라면 불가능하다는 것이므로 return
- 현재 세로선부터 확인한다.
현재 위치와 같은 가로선이라면, 현재 세로선부터 확인하고
다른 가로선이라는 0번째 세로선부터 확인한다.
만약, 현재 위치에 가로선을 못놓거나, 왼쪽에도 가로선이 존재한다면, continue
가로선을 놓을 수 있다면, 가로선을 놓고 dfs 실행한다.
이 때 dfs를 실행할 때 다음 가로선 위치가 아니라 다다음 가로선을 전달하는데, 가로선은 연속하여 놓을 수 없기 때문이다.
2) check
세로선 기준으로 위에서부터 아래로 내려오면서
현재 위치(오른쪽으로 연결된 가로선)나, 왼쪽에 가로선이 있다면 세로선을 그 위치로 이동시킨다.
다 이동하고 마지막 세로선이 현재 세로선과 다르다면 실패이므로 False 리턴
# i -> i 가능한지 확인
def check():
for i in range(n):
col = i
for j in range(h):
if graph[j][col] :
col += 1
elif col >0 and graph[j][col-1]:
col -=1
if col !=i :
return False
return True
# 가로선 놓기
def dfs(cnt, x,y ):
global ans
# 가능하다면 놓은 가로선 수 갱신
if check():
ans = min(ans,cnt)
return
# 현재 최솟값보다 크거나, 3 이상이면 실패
if cnt >= ans or cnt == 3 :
return
for i in range(x, h):
# 같은 행이면 y 부터 확인
if i == x:
k = y
# 다른 행이면 0부터 확인
else :
k = 0
# 가로선 놓을 수 있는 위치인지 확인하고 놓기
for j in range(k, n-1):
if graph[i][j] or graph[i][j+1]:
continue
if j > 0 and graph[i][j-1]:
continue
# 가로줄 만듬
graph[i][j] = 1
# 연속된 가로줄 만들지 않기 위해 j+2 호출
dfs(cnt+1, i ,j + 2)
graph[i][j] = 0
n,m,h = map(int,input().split())
graph = [ [0] * n for _ in range(h)]
ans = 4
for _ in range(m):
a, b = map(int,input().split())
graph[a-1][b-1] = 1
dfs(0, 0 ,0)
if ans < 4 :
print(ans)
else :
print(-1)
'개발 > algorithm' 카테고리의 다른 글
[백준 16235번] 나무 재테크 - python (0) | 2022.10.07 |
---|---|
[백준 16234번] 인구 이동 - python (1) | 2022.10.07 |
[백준 14890번] 경사로 - Python (1) | 2022.10.07 |
[백준 14889번] 스타트와 링크 - python (0) | 2022.10.07 |
[백준 23288번] 주사위 굴리기2 - python (0) | 2022.10.06 |