본문 바로가기
Algorithm/DFS&BFS&백트래킹&재귀

[백준] 2339번 석판 자르기

by HANNI하니 2023. 1. 18.

사용 언어 - Python3

2339번: 석판 자르기 (골드1, DFS 백트래킹 문제)

문제 ★분할 정복 문제

 

2339번: 석판 자르기

첫 번째 줄에는 석판의 크기 N(1 ≤ N ≤ 20)이 들어온다. 다음 줄부터 N줄에 걸쳐서 석판의 상태가 입력으로 들어온다. 여기서 1은 불순물을 의미하며, 2는 보석 결정체, 0은 불순물과 보석결정체가

www.acmicpc.net

 

정답

석판을 자를 수 있을 때까지 분할하는 "분할 정복" 알고리즘

(백준에서 정답자의 풀이를 보고 이해했습니다)

x의 start, end 범위 설정 sx, ex

y의 start, end 범위 설정 sy, ey

 

#정답

def f(sx, sy, ex, ey, hv):
    noise = [] #불순물
    dia = 0 #보석결정체
    
    for i in range(sx, ex):
        for j in range(sy, ey):
            if stones[i][j] == 1:
                noise.append([i, j])
            elif stones[i][j] == 2:
                dia += 1

    if dia == 1 and len(noise) == 0: 
        return 1 #다이아만 한개 -> 한개로만 나뉨
    if dia == 0 or len(noise) == 0:
        return 0 #둘다 없으면 -> 나눌게 없음 0

    count = 0 #자르는 횟수

    if hv != 1:
        for nx, ny in noise: #불순물의 x,y 좌표
            can_cut = True #자를 수 있는 여부
            for i in range(sy, ey):
                if stones[nx][i] == 2: #불순물이 있는 x줄(nx)에 있는 y 중 다이아가 있는 경우 
                    can_cut = False
                    break #다이아 있는 줄은 자를 수 없기 때문
            if can_cut: #nx줄에 있는 y 중 다이아가 없는 경우
                count += (f(sx, sy, nx, ey, 1) * f(nx + 1, sy, ex, ey, 1)) 
                # ex를 nx로 업데이트해준다. sx를 nx+1로 업데이트해준다.
                # x는 검토를 완료했으니, hv를 1로 바꾸어 2가 아닌 밑의 if문을 검사해서 y줄을 검사해준다.
                # 총 count = 왼쪽 석판에서 나온 count * 오른쪽 석판에서 나온 count

    if hv != 2:
        for nx, ny in noise:
            can_cut = True
            for i in range(sx, ex):
                if stones[i][ny] == 2: #불순물이 있는 y줄(ny)에 있는 x 중 다이아가 있는 경우
                    can_cut = False
                    break
            if can_cut: #ny줄에 있는 x 중 다이아가 없는 경우
                count += (f(sx, sy, ex, ny, 2) * f(sx, ny + 1, ex, ey, 2))
                # ey를 ny로 업데이트해준다. sy를 ny+1로 업데이트해준다.

    return count


n = int(input())

stones = [list(map(int, input().split())) for _ in range(n)]

result = f(0, 0, n, n, 0)

print(result if result != 0 else -1)

 


레퍼런스

  • 백준에서 다른 사람 정답 풀이 보는 법

1. 문제를 맞춘다.

2. 숏코딩이나 채점 현황에서 코드 공개한 사람들의 언어가 파랗게 하이퍼링크가 되어있다. 링크를 클릭하면 정답을 볼 수 있다.

 

  • 정답 깃허브
 

GitHub - yyeongeun/codingtest: 코딩테스트 공부

코딩테스트 공부. Contribute to yyeongeun/codingtest development by creating an account on GitHub.

github.com

  • 분할 정복 백준 문제 모음
 

분할 정복 단계

히스토그램에서 가장 큰 직사각형을 찾는 문제. (※인터넷에 널리 알려져 있는 풀이와 달리, 분할 정복 과정에서 "세그먼트 트리"라는 자료구조는 필요 없습니다.)

www.acmicpc.net

 

'Algorithm > DFS&BFS&백트래킹&재귀' 카테고리의 다른 글

[백준] 2580번 스도쿠  (0) 2023.01.19
[백준] 9663번 N-Queen  (0) 2023.01.19
[백준] 15652번 N과 M(4)  (0) 2023.01.18
[백준] 15651번 N과 M(3)  (0) 2023.01.18
[백준] 15650번 N과 M(2)  (0) 2023.01.18

댓글