[코드트리] 불안한 무빙워크

Jimeaning·2023년 9월 21일
0

코딩테스트

목록 보기
124/143

Python3

문제

코드트리 불안한 무빙워크

키워드

  • 시뮬레이션

문제 풀이

문제 요구사항

무빙워크의 레일은 시계 방향으로 회전한다.

무빙워크의 움직임)

1번 칸부터 2n-1번 칸은 한 번 회전할 때 2n번째 칸의 위치로 이동하게 되고 2n번째 칸은 1번째 칸의 위치로 이동하게 된다.

사람의 움직임)

각 사람은 1번 칸에 올라서서 n번 칸에서 내리게 됩니다. 사람이 어떤 칸에 올라가거나 이동하면 그 칸의 안정성은 즉시 1만큼 감소하게 되며 안정성이 0인 칸에는 올라갈 수 없다.

안정성 테스트)

  1. 무빙워크가 한 칸 회전합니다.
  2. 가장 먼저 무빙워크에 올라간 사람부터 무빙워크가 회전하는 방향으로 한 칸 이동할 수 있으면 이동합니다. 만약 앞선 칸에 사람이 이미 있거나 앞선 칸의 안정성이 0인 경우에는 이동하지 않습니다.
  3. 1번 칸에 사람이 없고 안정성이 0이 아니라면 사람을 한 명 더 올립니다.
  4. 안정성이 0인 칸이 k개 이상이라면 과정을 종료합니다. 그렇지 않다면 다시 위의 과정을 반복합니다.

단, 1~3 과정 중 n번 칸 위치에 사람이 위치하면 그 즉시 내리게 된다.

각 칸의 안정성은 시간에 지남에 따라 다시 상승하지 않는다.

과정이 종료될 때 몇 번째 실험을 하고 있었는지 구하는 프로그램

변수 및 함수 설명

  • n, k: 무빙워크의 길이 n, 실험을 종료하게 하는 안정성이 0인 판의 개수 k
    (2 ≤ n ≤ 100, 1 ≤ k ≤ 2n)
  • safe: 무빙워크 각각 칸의 안정성 (1 ≤ 판의 안정성 ≤ 1,000)
  • person: 현재 사람 위치
  • chk: 안정성이 0인 판의 개수
  • ans: 실험 개수
  • simulate(): 한 번의 실험을 하는 함수

풀이

(입력 및 선언)

  • 무빙워크의 길이와 실험을 종료하게 하는 판의 개수를 입력받는다
  • 무빙워크 각각 칸의 안전성을 입력받는다
  • 사람의 위치를 나타내는 deque, chk, ans 변수를 초기화한다.

(실험 과정)

  • 무빙워크의 맨 뒷 칸을 앞으로 보낸다

  • 사람의 위치도 맨 뒤에서 앞으로 보낸다

    (사람 내리기)

  • 만약 n번 칸에 사람이 있으면 내린다

    (사람 움직이기)

  • n회동안 반복한다

  • 이전 칸에 사람이 있고, 칸의 안정성이 0보다 크고, 이 칸에 사람이 없으면 이동한다.

  • 안정성을 1 감소시킨다. → 안정성이 0이면 chk를 1 증가시킨다.

    (사람 내리기)

  • 만약 n번 칸에 사람이 있으면 내린다

    (첫 칸 사람 올리기)

  • 첫 칸의 안정성이 0보다 크다면 사람을 올리고 안정성을 1 감소시킨다.

  • 만약 안정성이 0이면 chk를 1 증가시킨다.

(최종 출력하기)

  • 무한 반복문을 사용한다
  • simulate() 함수를 호출한다
  • 함수가 실행될 때마다 ans 값을 1씩 증가시킨다
  • 만약 chk 변수가 n이 되면 무한 반복문을 종료한다
  • ans를 최종 출력한다.

최종 코드

from collections import deque

n, k = map(int, input().split())
safe = deque(list(map(int, input().split())))

person = deque([0 for _ in range(n*2)])

chk = 0
ans = 0

def simulate():
    global chk

    # 무빙워크 뒷 칸을 앞으로
    safe.appendleft(safe.pop())
    person.appendleft(person.pop())

    # n번 칸 사람 내리기
    if person[n-1]:
        person[n-1] = 0

    # 사람 이동시키기
    # 현재 위치에 사람이 없고 안정성은 남아 있으면서 이전 위치에 사람이 있는 경우
    for i in range(n):
        if person[n] == 0 and safe[i] and person[i-1]:
            person[i] = 1
            person[i-1] = 0
            safe[i] -= 1

            # 안정성이 0이면 체크
            if safe[i] == 0:
                chk += 1

    # n번 칸 사람 내리기
    if person[n-1]:
        person[n-1] = 0
    
    # 사람 올리기
    if safe[0]:
        person[0] = 1
        safe[0] -= 1

        # 안정성이 0이면 체크
        if safe[i] == 0:
            chk += 1

while True:
    simulate()
    ans += 1

    # 안정성 0이 k개 이상이면 종료
    if chk >= k:
        break

print(ans)
profile
I mean

0개의 댓글