Posts [baekjoon] 20058. 마법사 상어와 파이어스톰 (python)
Post
Cancel

[baekjoon] 20058. 마법사 상어와 파이어스톰 (python)

20058. 마법사 상어와 파이어스톰 문제 바로가기

해결 방법

핵심 과정은 2가지 단계가 있다. (1. 회전하기 → 2. 얼음 녹이기)

  1. 회전하기 ★

    회전하기 규칙 그림

    위의 2가지 규칙을 이용하여 다음의 코드를 작성했다.

    rotate_board[i + j2][j + 2 ** q - i2 - 1] = board[i + i2][j + j2]

    이때 규칙을 사용한 부분만 남겨두면 다음과 같다.

    rotate_board[j2][2 ** q - i2 - 1] = board[i2][j2]

    즉, 기준이 되는 위치에 규칙을 적용시키면 원하는 동작을 할 수 있다.

  2. 얼음 녹이기

    ※ 주의 사항 : 회전한 보드 위에서 바로 녹이는 경우 안 녹는 얼음이 존재할 수 있기에 새로 0으로 초기화된 보드에 얼음 수를 저장해야 한다!

다음 Q만큼 반복한 뒤 최종적으로 남아있는 얼음 합과 가장 큰 덩어리를 차지하는 칸의 개수를 구하기 위해서 stack을 통해 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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
N, Q = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(2 ** N)]
Q_list = list(map(int, input().split()))

for q in Q_list:
    # 1. 회전하기
    rotate_board = [[0] * (2 ** N) for _ in range(2 ** N)]
    for i in range(0, 2 ** N, 2 ** q):
        for j in range(0, 2 ** N, 2 ** q):
						# 회전 규칙 적용!
            for i2 in range(2 ** q):
                for j2 in range(2 ** q):
                    rotate_board[i + j2][j + 2 ** q - i2 - 1] = board[i + i2][j + j2]
    dirs = [[-1, 0], [1, 0], [0, -1], [0, 1]]

    # 2. 얼음 녹이기
    board = [[0] * (2 ** N) for _ in range(2 ** N)]
    for y in range(2 ** N):
        for x in range(2 ** N):
            cnt = 0
            for d in range(4):
                ny, nx = y + dirs[d][0], x + dirs[d][1]
                if 0 <= ny < 2 ** N and 0 <= nx < 2 ** N and rotate_board[ny][nx] != 0:
                    cnt += 1
            if rotate_board[y][x] > 0:
                if cnt < 3:
                    board[y][x] = rotate_board[y][x] - 1
                else:
                    board[y][x] = rotate_board[y][x]


# 3. 남아있는 얼음 합과 가장 큰 덩어리를 차지하는 칸의 개수 구하기
ice_sum = 0  # 남아있는 얼음 합에 대한 변수
ice_amount_list = [0] # 얼음 덩어리 개수를 저장할 리스트
visited = [[False] * (2 ** N) for _ in range(2 ** N)]
for y in range(2 ** N):
    for x in range(2 ** N):
        temp = []
        if board[y][x] != 0 and visited[y][x] == False:
						# stack 이용
            temp.append([y, x])
            visited[y][x] = True
            ice_sum += board[y][x]
            cnt = 1
            while temp:
                test = temp.pop()
                ty, tx = test[0], test[1]
                for d in range(4):
                    nty, ntx = ty + dirs[d][0], tx + dirs[d][1]
                    if 0 <= nty < 2 ** N and 0 <= ntx < 2 ** N and visited[nty][ntx] == False and board[nty][ntx] != 0:
                        temp.append([nty, ntx])
                        visited[nty][ntx] = True
                        ice_sum += board[nty][ntx]
                        cnt += 1
            ice_amount_list.append(cnt)


print(ice_sum)
print(max(ice_amount_list))
This post is licensed under CC BY 4.0 by the author.

[baekjoon] 17779. 게리맨더링2 (python)

[baekjoon] 19237. 어른상어 (python)

Comments powered by Disqus.