99클럽 코테 스터디 7일차 TIL (고고학 최고의 발견, 균형잡힌 세상)

정내혁·2024년 4월 18일
1

TIL

목록 보기
7/8

99클럽 코테 스터디

1번 상당히 빡셌다. 1번 푸는데 오래 걸렸는데 2번은 백준에서 예전에 푼 문제라서 바로 끝나버렸다.

지금까지 내가 본 건 전부 프로그래머스 문제였다가 백준 문제가 처음 나왔는데 실버4에 이미 푼 문제라 싱겁게 끝났다.

1번 문제 고고학 최고의 발견 : https://school.programmers.co.kr/learn/courses/30/lessons/131702

2번 문제 균형잡힌 세상 : https://www.acmicpc.net/problem/4949

출처 : 프로그래머스, 백준


1번 문제 고고학 최고의 발견


풀이 접근

맨 윗줄의 모든 칸(최대 8칸)을 몇 번씩 돌릴 지(경우의 수 최대 65536) 확정지으면 그 아래 칸들은 전부 확정된다.

맨 윗줄을 돌리는 경우의 수는 최대 4^8 = 65536가지이다. 이를 픽스해 두면, 맨 윗줄의 각 칸들의 최종적인 상태는 그 아랫칸이 유일하게 결정하게 된다.

따라서 맨 윗줄의 각 칸의 화살표가 12시를 향하도록 그 아랫줄의 각 칸들을 결정하게 되고, 그러고 나면 3번째 줄을 유일하게 결정해서 2번째 줄이 다 12시를 향하도록 해야 하고 ... 맨 밑줄까지 반복할 수 있다.

맨 밑 줄은 그 아랫줄이 없으므로, 유일하게 결정되고 나면 맨 밑줄의 모든 칸이 12시를 향하는지 확인하고, 만약 그렇다면 solve에 성공한 것이므로 총 회전 횟수가 최소였는지만 체크해서 갱신하면 된다.


코드 (Python3, 통과, 최대 6067.64ms, 10.4MB)

구현 방식이 중구난방 의식의 흐름대로라 남이 알아보기 굉장히 어려운 코드이다.

rotate_number를 읽는 방향이 실제 표와 반대라거나, rotated의 테두리에 0을 두르는데 위랑 오른쪽에 두른다거나...

그나마 셀프 세션 발표하느라 주석이라도 많이 달았다.

def solution(clockHands):
    answer = 0
    n = len(clockHands)
    least = 192
    for rotate_number in range(4**n):  # 첫 줄 돌리는 경우의 수 4**n(최대 65536)가지
        rotated_cnt = 0  # 회전 횟수
        solved = True  # 첫줄 이상하게 돌리면 solve 실패할 수도 있음
        rotated = [[0]*n]  # rotated[i+1][j]는 clockHands[i][j] 칸을 몇 번 회전시켰는지이다. 테두리 바깥을 없는 걸로 처리하기 위해 0 둘러주기
        for i in range(n-1):
            rotated.append([])
            next_rotate_number = 0
            for j in range(n):
                r = rotate_number % 4  # rotate_number(의 4진수)의 1의 자리가 맨 앞(왼쪽) 칸의 회전 횟수
                rotated_cnt += r
                rotate_number //= 4
                rotated[i+1].append(r)
            rotated[i+1].append(0)  # 테두리 바깥을 없는 걸로 처리하기 위해 0 둘러주기
            for j in range(n):
                next_rotate_number += (-clockHands[i][j] - sum(rotated[i+1][j-k] for k in range(-1, 2)) - rotated[i][j])%4 * 4**j
                # 위에서부터 아래로 내려오므로 ㅗ 모양 4개 칸이 (i,j) 칸에 영향을 이미 주었고 그 아래 칸이 다음 줄에서 영향을 줄 것
            rotate_number = next_rotate_number
        rotated.append([])
        for j in range(n):  # 맨 마지막 줄만 따로 돌려서 그 다음 줄로 맞추는 게 아니고 solve 확인
            r = rotate_number % 4
            rotated_cnt += r
            rotate_number //= 4
            rotated[n].append(r)
        rotated[n].append(0)
        for j in range(n):
            if (clockHands[n-1][j] + sum(rotated[n][j-k] for k in range(-1, 2)) + rotated[n-1][j]) % 4:
                solved = False  # 맨밑줄에서 틀린 칸 있으면 배제
                break
        if solved and rotated_cnt < least:  # 회전 횟수 최소이면 갱신
            least = rotated_cnt
    answer = least
    return answer

2번 문제 균형잡힌 세상


풀이 접근

작년 1월 31일에 푼 문제이다. 작년 1월 11일에 백준을 가입했으니 코딩 20일차에 푼 문제이므로... 굉장히 풀이가 구리다. 1번 문제를 풀고 시간이 충분히 남았으면 코드를 수정해서 최적화를 시켜볼 텐데, 그럴 시간이 부족했다.

코드를 읽어보니 그냥 조건 이해 + 구현 문제였다.


코드 (Python3, 통과, 최대 360ms, 31256KB)

while True:
    sent=str(input())
    if sent=='.':
        break
    sent=list(sent[:-1])
    key=True
    brackets=[]
    while sent!=[]:
        a=sent.pop()
        if a in [')',']']:
            brackets.append(a)
        elif a=='(':
            if brackets==[]:
                key=False
                break
            b=brackets.pop()
            if b==']':
                key=False
                break
        elif a=='[':
            if brackets==[]:
                key=False
                break
            b=brackets.pop()
            if b==')':
                key=False
                break
    if brackets!=[]:
        key=False
    if key:
        print('yes')
    else:
        print('no')
profile
개발자 꿈나무 정내혁입니다.

0개의 댓글