Posts [백준] #20061 모노미노도미노2 Python (파이썬)
Post
Cancel

[백준] #20061 모노미노도미노2 Python (파이썬)

모노미노도미노2

문제링크

https://www.acmicpc.net/problem/20061

코드

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import sys
sys.stdin = open("input.txt",'r')
n = int(input())
# 빨간 보드 
red_green = [[0]*4 for _ in range(10)]
# 초록 보드

# 파란 보드
red_blue = [[0]*10 for _ in range(4)]

# 빨간 + 초록 
# 빨강의 경계선(행) 까지 간다음에.. 끝까지..
# 한칸씩 내려가기 부딪히면 전으로 돌아가는거
# 특별한 행에 위치한지 확인
    # 지우기, 만들기
# 4칸 다 찾는지 확인
    # 지우기 만들기
# 빨간 + 파란 
# 빨강 경계선 (열) 까지 간다음에 .. 끝까지
# 한칸씩 오른쪽으로 부딪히면 전으로 돌아가는거
# 특별한 열에 위치했는지 확인
    # 지우기, 만들기
# 4칸 다 찾는지 확인
    # 지우기 만들기

def green_remove(red_green,ans):
    while True:
        for i in range(10):
            if red_green[i] == [1,1,1,1]:
                ans += 1
                red_green[i] = [0,0,0,0]
                for x in range(i,0,-1):
                    red_green[x] = red_green[x-1]
                red_green[0] = [0,0,0,0]
        else:
            break

    return red_green, ans

def blue_remove(red_blue,ans):
    while True:
        for j in range(10):
            if (red_blue[0][j],red_blue[1][j],red_blue[2][j],red_blue[3][j]) == (1,1,1,1):
                ans += 1
                red_blue[0][j],red_blue[1][j],red_blue[2][j],red_blue[3][j] = 0,0,0,0
                for y in range(j,0,-1):
                    red_blue[0][y],red_blue[1][y],red_blue[2][y],red_blue[3][y] = red_blue[0][y-1],red_blue[1][y-1],red_blue[2][y-1],red_blue[3][y-1]
        else:
            break
    return red_blue, ans

def blue_special(red_blue):
    cnt = 0
    for i in range(4):
        if red_blue[i][4] == 1 or red_blue[i][5] == 1:
            cnt += 1
            break

    if cnt > 0:
        while True:
            if  (red_blue[0][4],red_blue[1][4],red_blue[2][4],red_blue[3][4]) == (0,0,0,0) and (red_blue[0][5],red_blue[1][5],red_blue[2][5],red_blue[3][5]) == (0,0,0,0):
                break

            for j in range(9,4,-1):

                red_blue[0][j],red_blue[1][j],red_blue[2][j],red_blue[3][j] = red_blue[0][j-1],red_blue[1][j-1],red_blue[2][j-1],red_blue[3][j-1]
            red_blue[0][4],red_blue[1][4],red_blue[2][4],red_blue[3][4] = 0,0,0,0

    return red_blue

def green_special(red_green):
    cnt = 0
    for j in range(4):
        if red_green[4][j] == 1 or red_green[5][j] == 1:
            cnt += 1
            break
    if cnt > 0:
        while True:
            if red_green[4] == [0,0,0,0] and red_green[5] == [0,0,0,0]:
                break
            for i in range(9,4,-1):
                red_green[i] = red_green[i-1]
            red_green[4] = [0,0,0,0]
    return red_green

ans = 0
for _ in range(n):
    t,x,y = map(int,input().split())
    
    if t == 1:
        # 빨강 + 초록
        nx, ny = x,y
        for i in range(1,10-x):

            if red_green[x+i][y] == 0:
                nx, ny = x+i, y
            else:
                nx, ny = x-1+i, y
                break
        red_green[nx][ny] = 1
        # 빨강 + 파랑
        nx, ny = x,y
        for j in range(1,10-y):
            if red_blue[x][y+j] == 0:
                nx, ny = x,y+j
            else:
                nx, ny = x,y-1+j
                break
        red_blue[nx][ny] = 1
    elif t == 2:
        nx, ny = x, y
        a, b = x, y+1
        # 빨강 + 초록
        for i in range(1,10-x):
            if red_green[x+i][y] == 0 and red_green[x+i][y+1] == 0:
                nx, ny = x+i,y
                a, b = x+i, y+1
            else:
                nx, ny = x+i-1,y
                a, b = x+i-1, y+1
                break
        red_green[nx][ny] = 1
        red_green[a][b] = 1
        # 빨강 + 파랑
        nx, ny = x, y
        a, b = x, y+1
        for j in range(1,9-y):
            if red_blue[x][y+j] == 0 and red_blue[x][y+j+1] == 0:
                nx, ny = x, y+j
                a, b = x, y+1+j
            else:
                nx, ny = x, y+j-1
                a, b = x, y+j
                break
        red_blue[nx][ny] = 1
        red_blue[a][b] = 1

    elif t == 3: # info = [[x,y],[x+1,y]]
        nx, ny = x+1,y
        for i in range(1,9-x):
            if red_green[x+1+i][y] == 0 and red_green[x+i][y] == 0:
                nx, ny = x+1+i,y
            else:
                nx, ny = x+i,y
                break
        red_green[nx][ny] = 1
        red_green[nx-1][ny] = 1

        nx, ny = x+1,y
        for j in range(1,10-y):
            if red_blue[x][y+j] == 0 and red_blue[x+1][y+j] == 0:
                nx, ny = x+1,y+j
            else:
                nx, ny = x+1,y-1+j
                break
            
        red_blue[nx][ny] = 1
        red_blue[nx-1][ny] = 1

    red_blue,ans = blue_remove(red_blue,ans)
    red_green,ans = green_remove(red_green,ans)
    red_blue = blue_special(red_blue)
    red_green = green_special(red_green)

# print(red_blue)
# print(red_green)

print(ans)
total = 0
# 초록색
for i in range(6,10):
    total += sum(red_green[i])
for i in range(4):
    total += sum(red_blue[i])
print(total)

풀이

green_remove : 빨강 + 초록 판에서 네개 꽉찼을때 지워주는 함수

blue_remove : 빨강 + 파랑 판에서 네개 꽉찼을때 지워주는 함수

blue_special : 빨강 + 파랑 판에서 연한 부분에 블록이 있을때 이동시켜주는 함수

green_special : 빨강 + 초록 판에서 연한 부분에 블록이 있을 때 이동시켜주는 함수

일단 아예 초기에 빨강+초록 판이랑 빨강 + 파랑 배열을 만들어버렸다. 아래그림에서 검은색 2차원 배열이랑 빨간색 이차원 배열

모노미노도미노2

4개가 찼는지 확인하는 remove 함수들은 4개 꽉찬게 여러 행 또는 열일 수 있으니 while 문을 써서 그러한 줄이 아예 없을때까지 반복시켜주었다.

special 함수의 경우에도 연한 부분에 블록이 있는지 확인하고, 아예 다 비어져있을때까지 계속해서 아래 혹은 오른쪽으로 이동하도록 while 문을 통해 반복해주었다.

문제에서 4개가 꽉찬 경우와 연한 부분에 블록이 있을 경우 4개 꽉찬 부분을 먼저 해결해주는걸 우선순위라고 했으니까 순서는 아래와 같이 코드를 작성하였다.

1
2
3
4
red_blue,ans = blue_remove(red_blue,ans)
red_green,ans = green_remove(red_green,ans)
red_blue = blue_special(red_blue)
red_green = green_special(red_green)

그리고 문제에서 출력으로 요구하는 답이 줄을 지울때마다 점수가 올라가므로 remove 함수에서

if red_green[i] == [1,1,1,1]: 을 만족할때마다 ans += 1 을 해주었다.

그리고 초록판과 파랑판에 있는 블록의 개수는 total 값으로 red_greenred_blue 에서 각각 총 합을 구했다 ( 어차피 블록이 있는 부분이 1 이니까 개수 구하는것은 이차원 배열의 총합과 같다)

This post is licensed under CC BY 4.0 by the author.

[백준] #20055 컨베이어 벨트 위의 로봇 Python (파이썬)

[Algorithm] 정렬 알고리즘 (Bubble Sort, Selection Sort, Insertion sort, Counting sort, Merge Sort, Quick sort, Python Sort) 기본 개념과 Python 코드

Loading comments from Disqus ...