본문 바로가기
코딩테스트

[백준] 16131 기숙사 서바이벌 (Dormvival Games) - python

by CuckooBird 2023. 1. 28.

백준 16131 기숙사 서바이벌 (Dormvival Games) - 실버 4

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

 

16131번: 기숙사 서바이벌 (Dormvival Games)

서울 S 과학고의 기숙사는 매우 특이한 체계를 가지기로 유명하다. 기숙사에는 수많은 방이 있고, 각각의 방에는 번호가 붙어져 있어 번호가 작을수록 더 좋은 질의 방을 갖게 된다. 이 기숙사의

www.acmicpc.net


코드 (성공x)

Try 1.  코드길이 1280B

틀렸습니다가 뜨는 코드입니다.

import sys
N, A, B, M = map(int, sys.stdin.readline().rstrip().split())
room = dict(zip(range(1, N+1), range(1, N+1)))
score = list(map(int, sys.stdin.readline().rstrip().split()))
minus = []
minus = list(map(int, sys.stdin.readline().rstrip().split()))
feel_good = 0
for i in range(N):
    score[i] = score[i] - minus[i]
def room_change(good, bad):
    temp = 0
    if score[good] >= 0 and score[bad] >= 0 and score[bad] - score[good] >= 2:
        temp = good
        good = bad
        bad = temp
        score[good] = 2
        score[bad] = -2
    elif score[good] < 0 and score[bad] >= 0:
        temp = good
        good = bad
        bad = temp
        score[good] = 2
        score[bad] = -2
    elif score[good] < 0 and score[bad] < 0 and score[bad] - score[good] >= 4:
        temp = good
        good = bad
        bad = temp
        score[good] = 2
        score[bad] = -2
    else:
        score[good] = 0
        score[bad] = 0
continuity = []
cnt = 0
for m in range(M):
    for i in range(1, N-1):
        room_change(room[i], room[i+1])
    reverse_dic = {v:k for k,v in room.items()}
    if abs(reverse_dic[1]-reverse_dic[7]) <= B:
        feel_good += 1
        cnt += 1
        continuity.append(cnt)
    else:
        cnt = 0
print(feel_good, max(continuity))
  • 점수 정보를 매번 입력받아야 함을 놓쳤습니다.
  • 함수의 임시적인 매개변수로는 딕셔너리의 값을 바꿀 수 없었습니다. -> 함수삭제
  • 점수를 매 조건문마다 바꾸면 바뀐 점수가 다음 조건에 영향을 줄 수 있음을 놓쳤습니다.

Try 2. 코드 길이 1690B

틀렸습니다가 뜨는 코드입니다.

import sys
N, A, B, M = map(int, sys.stdin.readline().rstrip().split())
room = dict(zip(range(1, N+1), range(1, N+1)))
if A - 1 <= B:
    feel_good = 1
    cnt = 1
else:
    feel_good = 0
    cnt = 0
continuity = []
for _ in range(M-1):
    good = []
    bad = []
    score = [0] + list(map(int, sys.stdin.readline().rstrip().split()))
    minus = [0] + list(map(int, sys.stdin.readline().rstrip().split()))
    for i in range(1, N+1):
        score[i] = score[i] - minus[i]
    for i in range(1, N):
        temp = 0
        if score[room[i]] >= 0 and score[room[i+1]] >= 0 and score[room[i+1]] - score[room[i]] >= 2:
            temp = room[i]
            room[i] = room[i+1]
            room[i+1] = temp
            good.append(room[i])
            bad.append(room[i+1])
        elif score[room[i]] < 0 and score[room[i+1]] >= 0:
            temp = room[i]
            room[i] = room[i+1]
            room[i+1] = temp
            good.append(room[i])
            bad.append(room[i+1])
        elif score[room[i]] < 0 and score[room[i+1]] < 0 and score[room[i+1]] - score[room[i]] >= 4:
            temp = room[i]
            room[i] = room[i+1]
            room[i+1] = temp
            good.append(room[i])
            bad.append(room[i+1])
    score = [0] + [0 for i in range(N)]
    good = list(set(good))
    bad = list(set(bad))
    for g in good:
        score[g] = -2
    for b in bad:
        score[b] = 2
    reverse_dic = {v:k for k,v in room.items()}
    if abs(reverse_dic[1]-reverse_dic[A]) <= B:
        feel_good += 1
        cnt += 1
        continuity.append(cnt)
    else:
        cnt = 0
        continuity.append(cnt)
print(feel_good, max(continuity))
  • score을 다시 입력 받는 과정에서 이전에 2와 -2를 넣는 과정이 말짱 도루묵이 됐습니다.

 


Search 🔍

  • 딕셔너리
    - for문으로 딕셔너리에 값 집어넣는 방법

    dic = dict(zip(range(1, N+1), range(1, N+1)))
    zip함수는 동일한 개수의 요소 값을 갖는 시퀀스 자료형을 묶어주는 역할을 합니다.
    zip함수에 들어가는 앞의 매개변수는 key값에 들어가게 되고, 뒤의 매개변수는 value값에 들어갑니다.

    위에 한 말과 같이 앞 뒤 매개변수의 개수가 같아야 짝지어 묶어줄 수 있습니다.

    - value값으로 key값 찾는 법 (key값과 value값 반대로 돌리는 법)
          value값으로 key값을 찾는 것보다는 key값과 value값을 바꿔서 바뀐 key값으로 value를 찾는게 더 효율적일 것 같아서 이 방법을 찾았습니다.

    reverse_dic = {v:k for k,v in dic.items()}
    리스트에 for문으로 집어넣듯이 넣고, v:k 를 k,v 순으로 넣어 반대로 돌려줍니다.
    dic의 key와 value를 가져오는 것이므로 items()로 모두를 가져옵니다.

  • 절대값 함수

    abs( A - B )
    자주 쓰지 않으니 그만큼 까먹는 것 같습니다. 긴가민가 해서 찾아봤습니다.

  • 리스트
    - 중복 제거하는 방법 (list -> set -> list)

    good = list(set(good))
    리스트를 set로 바꾸면 중복이 제거되고, 그것을 다시 리스트에 넣으면 중복제거된 리스트가 완성됩니다.
    set는 집합 자료형으로써, 

      -  중복을 허용하지 않는다.
      -  순서가 없다(Unordered).

    의 규칙이 있기 때문입니다.
 

궁금점 ❓

  • 함수 매개변수로 딕셔너리의 내용을 바꿀 수 없는 이유

후기

눈알이가 빠질거 같아서 오늘은 이쯤에서 후퇴하겠습니다...