Search
Duplicate

기둥과 보 설치

문제 설명 및 제한사항

아이디어 및 해결 방법

코드

from collections import Counter, defaultdict N = 0 COL, ROW = 0, 1 COLHEAD, COLBOTTOM = 2, 3 ROWLEFT, ROWRIGHT = 4, 5 REMOVE, ADD = 0, 1 def is_valid(rows, cols, cnt): for x, y in cols: predicates = [] # 바닥 위에 있거나 predicates.append( y == 0 ) # 보의 한쪽 끝 부분 위에 있거나 predicates.append( cnt[(x, y)][ROW] > 0 ) # 다른 기둥 위에 있거나 predicates.append( cnt[(x, y)][COLHEAD] == 1 ) if not any(predicates): return False for x, y in rows: predicates = [] # 한쪽 끝 부분이 기둥 위에 있거나. predicates.append( cnt[(x, y)][COLHEAD] == 1 or cnt[(x+1, y)][COLHEAD] == 1 ) # 양쪽 끝 부분이 다른 보와 동시에 연결되어 있어야 함. predicates.append( cnt[(x, y)][ROWRIGHT] == 1 and cnt[(x+1, y)][ROWLEFT] == 1 ) if not any(predicates): return False return True def solution(n, build_frame): global N N = n # 각 좌표에 존재하는 기둥의 수와, 각 좌표에 걸친 보의 개수를 세는 # 카운터를 관리합니다. cnt = defaultdict(Counter) # 기둥과 보의 좌표를 나타내는 리스트입니다. cols, rows = [], [] for x, y, typ, op in build_frame: if typ == COL and op == ADD: # 기둥을 세웁니다. cnt[(x, y)][COLBOTTOM] += 1 cnt[(x, y+1)][COLHEAD] += 1 cols.append( (x, y) ) if not is_valid(rows, cols, cnt): # 옳지 않은 구조이면, 원상복구합니다. cnt[(x, y)][COLBOTTOM] -= 1 cnt[(x, y+1)][COLHEAD] -= 1 cols.remove( (x, y) ) if typ == COL and op == REMOVE: # 기둥을 제거합니다. cnt[(x, y)][COLBOTTOM] -= 1 cnt[(x, y+1)][COLHEAD] -= 1 cols.remove( (x, y) ) if not is_valid(rows, cols, cnt): # 옳지 않은 구조이면, 원상복구합니다. cnt[(x, y)][COLBOTTOM] += 1 cnt[(x, y+1)][COLHEAD] += 1 cols.append( (x, y) ) if typ == ROW and op == ADD: # 보를 설치합니다. cnt[(x, y)][ROW] += 1 cnt[(x+1, y)][ROW] += 1 cnt[(x, y)][ROWLEFT] += 1 cnt[(x+1, y)][ROWRIGHT] += 1 rows.append( (x, y) ) if not is_valid(rows, cols, cnt): # 옳지 않은 구조이면, 원상복구합니다. cnt[(x, y)][ROW] -= 1 cnt[(x+1, y)][ROW] -= 1 cnt[(x, y)][ROWLEFT] -= 1 cnt[(x+1, y)][ROWRIGHT] -= 1 rows.remove( (x, y) ) if typ == ROW and op == REMOVE: # 보를 제거합니다. cnt[(x, y)][ROW] -= 1 cnt[(x+1, y)][ROW] -= 1 cnt[(x, y)][ROWLEFT] -= 1 cnt[(x+1, y)][ROWRIGHT] -= 1 rows.remove( (x, y) ) if not is_valid(rows, cols, cnt): # 옳지 않은 구조이면, 원상복구합니다. cnt[(x, y)][ROW] += 1 cnt[(x+1, y)][ROW] += 1 cnt[(x, y)][ROWLEFT] += 1 cnt[(x+1, y)][ROWRIGHT] += 1 rows.append( (x, y) ) result = [] for (x, y) in cnt.keys(): for typ, n in cnt[(x, y)].items(): if typ == COLBOTTOM and n > 0: result.append([x, y, COL]) if typ == ROWLEFT and n > 0: result.append([x, y, ROW]) result.sort() return result
Python
복사

출처

프로그래머스 코딩테스트 연습 https://school.programmers.co.kr/learn/challenges