모노미노도미노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차원 배열이랑 빨간색 이차원 배열
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_green
과 red_blue
에서 각각 총 합을 구했다 ( 어차피 블록이 있는 부분이 1 이니까 개수 구하는것은 이차원 배열의 총합과 같다)