풀이 시간
구현 방식
- "20061: 모노미노도미노 2" 문제와 다른 점은 아래와 같다
1) 초록색 보드에서 점수를 얻고 행이 사라지거나, 파란색 보드에서 점수를 얻고 열이 사라진다면, 그 후에 "타일 단위로" 경계나 다른 블록을 만나기 전까지 내려줘야한다 (모래알처럼 우수수 떨어지는 게 아님)
2) 연한 칸에 대한 처리를 마친 후에 한 번 더 get_score()과 gravity()를 호출하여 점수 획득과 행 또는 열 제거를 수행해주어야한다
- 타일 단위로 중력을 받는 부분을 구현해주기 위해 타일의 type 별로 1, 2, 3의 숫자로 green, blue에 표시해주었다
- gravity(color)
-> green인 경우에는 tile이 2인 경우를 주의해야한다
-> while문에서 green[row+1][j+1] == 0까지 만족하면 swap을 해주고, idx_flag를 이용해 다음 열은 pass 하도록 해줘야한다
-> blue인 경우에는 tile이 3인 경우를 주의해야한다
-> while문에서 blue[i+1][col+1] == 0까지 만족하면 swap을 해주고, idx_flag를 이용해 다음 행은 pass 하도록 해줘야한다
코드
import sys
green = [[0] * 4 for _ in range(10)]
blue = [[0] * 10 for _ in range(4)]
def move_green(t, x, y):
if t == 1:
while True:
if x >= 10:
green[x-1][y] = 1; break
if green[x][y] != 0:
green[x-1][y] = 1; break
x += 1
elif t == 2:
while True:
if x >= 10:
green[x-1][y] = 2; green[x-1][y+1] = 2; break
if green[x][y] != 0 or green[x][y+1] != 0:
green[x-1][y] = 2; green[x-1][y+1] = 2; break
x += 1
elif t == 3:
while True:
if x >= 10:
green[x-1][y] = 3; green[x-2][y] = 3; break
if green[x][y] != 0:
green[x-1][y] = 3; green[x-2][y] = 3; break
x += 1
def move_blue(t, x, y):
if t == 1:
while True:
if y >= 10:
blue[x][y-1] = 1; break
if blue[x][y] != 0:
blue[x][y-1] = 1; break
y += 1
elif t == 2:
while True:
if y >= 10:
blue[x][y-1] = 2; blue[x][y-2] = 2; break
if blue[x][y] != 0:
blue[x][y-1] = 2; blue[x][y-2] = 2; break
y += 1
elif t == 3:
while True:
if y >= 10:
blue[x][y-1] = 3; blue[x+1][y-1] = 3; break
if blue[x][y] != 0 or blue[x+1][y] != 0:
blue[x][y-1] = 3; blue[x+1][y-1] = 3; break
y += 1
def gravity(color):
if color == "green":
for i in range(10-2, 4, -1):
idx_flag = -1
for j in range(4):
if idx_flag == j: continue
if green[i][j] == 1 or green[i][j] == 3:
row = i
while True:
if 0 <= row+1 < 10 and green[row+1][j] == 0:
green[row+1][j] = green[row][j]; green[row][j] = 0
row += 1
else: break
elif green[i][j] == 2:
row = i
while True:
if 0 <= row+1 < 10 and green[row+1][j] == 0 and green[row+1][j+1] == 0:
green[row+1][j] = green[row][j]; green[row][j] = 0
green[row+1][j+1] = green[row][j+1]; green[row][j+1] = 0
row += 1
else: break
idx_flag = j+1
elif color == "blue":
for j in range(10-2, 4, -1):
idx_flag = -1
for i in range(4):
if idx_flag == i: continue
if blue[i][j] == 1 or blue[i][j] == 2:
col = j
while True:
if 0 <= col+1 < 10 and blue[i][col+1] == 0:
blue[i][col+1] = blue[i][col]; blue[i][col] = 0
col += 1
else: break
elif blue[i][j] == 3:
col = j
while True:
if 0 <= col+1 < 10 and blue[i][col+1] == 0 and blue[i+1][col+1] == 0:
blue[i][col+1] = blue[i][col]; blue[i][col] = 0
blue[i+1][col+1] = blue[i+1][col]; blue[i+1][col] = 0
col += 1
else: break
idx_flag = i+1
def get_score(color):
global total_score
gravity_flag = False
if color == "green":
for i in range(10):
check = 0
for j in range(4):
if green[i][j] == 0: break
check += 1
if check == 4:
green[i] = [0, 0, 0, 0]
total_score += 1
gravity_flag = True
elif color == "blue":
for j in range(6, 10):
check = 0
for i in range(4):
if blue[i][j] == 0: break
check += 1
if check == 4:
for x in range(4):
blue[x][j] = 0
total_score += 1
gravity_flag = True
return gravity_flag
def light_check(color):
if color == "green":
row_cnt = 0
for i in range(4, 6):
if sum(green[i]) != 0: row_cnt += 1
for _ in range(row_cnt):
for i in range(10-1, 4, -1):
green[i] = green[i-1]
green[4] = [0, 0, 0, 0]
elif color == "blue":
col_cnt = 0
for j in range(4, 6):
for i in range(4):
if blue[i][j] != 0: col_cnt += 1; break
for _ in range(col_cnt):
for j in range(10-1, 4, -1):
for i in range(4):
blue[i][j] = blue[i][j-1]
for i in range(4):
blue[i][4] = 0
N = int(sys.stdin.readline()[:-1])
cmd = []
for n in range(N):
t, x, y = map(int, sys.stdin.readline()[:-1].split())
cmd.append((t, x, y))
total_score = 0
for n in range(N):
t, x, y = cmd[n]
move_green(t, x, y)
gravity_green_flag = get_score("green")
if gravity_green_flag: gravity("green")
light_check("green")
gravity_green_flag = get_score("green")
if gravity_green_flag: gravity("green")
move_blue(t, x, y)
gravity_blue_flag = get_score("blue")
if gravity_blue_flag: gravity("blue")
light_check("blue")
gravity_blue_flag = get_score("blue")
if gravity_blue_flag: gravity("blue")
print(total_score)
count = 0
for i in range(6, 10):
for j in range(4):
if green[i][j] != 0: count += 1
for i in range(4):
for j in range(6, 10):
if blue[i][j] != 0: count += 1
print(count)
결과
- IndexError: gravity 함수에서 "green + 타일이 2번인 경우"와 "blue + 타일이 3번인 경우"에 idx_flag 변수를 통해 다음 열 또는 행을 건너뛸 수 있도록 구현하여 해결함