coding test

[파이썬] 5099. 피자 굽기

잔망루피 2021. 1. 26. 13:03

※ SW Expert 아카데미의 문제를 무단 복제하는 것을 금지합니다.


N개의 피자를 동시에 구울 수 있는 화덕이 있다. 피자는 치즈가 모두 녹으면 화덕에서 꺼내며, 치즈의 양은 피자마다 다르다.

1번부터 M번까지 M개의 피자를 순서대로 화덕에 넣을 때, 치즈의 양에 따라 녹는 시간이 다르기 때문에 꺼내지는 순서는 바뀔 수 있다.

주어진 조건에 따라 피자를 구울 때, 화덕에 가장 마지막까지 남아있는 피자 번호를 알아내는 프로그램을 작성하시오.



- 피자는 1번위치에서 넣거나 뺄 수 있다.
- 화덕 내부의 피자받침은 천천히 회전해서 1번에서 잠시 꺼내 치즈를 확인하고 다시 같은 자리에 넣을 수 있다.
- M개의 피자에 처음 뿌려진 치즈의 양이 주어지고, 화덕을 한 바퀴 돌 때 녹지않은 치즈의 양은 반으로 줄어든다. 이전 치즈의 양을 C라고 하면 다시 꺼냈을 때 C//2로 줄어든다.
- 치즈가 모두 녹아 0이 되면 화덕에서 꺼내고, 바로 그 자리에 남은 피자를 순서대로 넣는다.



[입력]

첫 줄에 테스트 케이스 개수 T가 주어진다.  1<=T<=50

다음 줄부터 테스트 케이스의 첫 줄에 화덕의 크기 N과 피자 개수 M이 주어지고, 다음 줄에 M개의 피자에 뿌려진 치즈의 양을 나타내는 Ci가 주어진다.

3<=N<=20, N<=M<=100, 1<=Ci<=20

[출력]

각 줄마다 "#T" (T는 테스트 케이스 번호)를 출력한 뒤, 번호를 출력한다.

입력 출력
3
3 5
7 2 6 5 3
5 10
5 9 3 9 9 2 5 8 7 1
5 10
20 4 5 7 3 15 2 1 2 2
#1 4
#2 8
#3 6

 

🎁 나의 풀이

문제를 이해 못했다 ㅠㅠ 

입출력 보고도 첫 번째 케이스에서 막혔음. 알고보니 값이 아니라 인덱스;;

 

 

🎀 다른사람 풀이

 

TC=int(input())

for tc in range(1, TC+1):
  N, M=map(int, input().split())		# 화덕 크기, 피자 개수
  Data=list(map(int, input().split()))		# 치즈
  Q=[]
  for i in range(N):					# 화덕의 크기만큼 피자 올리기
    Q.append([Data[i], i])
  
  i=0
  while len(Q) != 1 :
    Q[0][0] //=2			# 치즈가 익음
    if Q[0][0] == 0 :
      if N+i < M :  # 화로크기 + i < 피자 개수
        Q.pop(0)      
        Q.append([Data[N+i], N+i])    # 그 다음 피자 넣기
        i+=1
      elif N+i >= M :               # 넣을 피자 없음  
        Q.pop(0)
    else:
      Q.append(Q.pop(0))          # 피자 넣기

  print(f"#{tc} {Q[0][1]+1}")

 

화덕의 크기 N만큼 리스트 Q에 Data 값과 인덱스를 리스트 형태로 추가한다. 

마지막까지 남아있는 피자 번호를 알아내기 위해 Q의 길이가 1이 아닐 동안 반복한다. 

Q의 첫번째 값을 2로 나눈다. Q값이 0이랑 같으면 그 다음 피자를 올린다. 없으면 Q에서 값을 뺀다.

Q 값이 0이 아니면 빼서 끝에 추가한다.

문제에서 화덕 번호가 1부터여서 1을 더함.

 

TC=int(input())

for tc in range(1, TC+1):
  N, M=map(int, input().split())		# 화덕 크기, 피자 개수
  q=list(map(int, input().split()))		# 치즈
  q2=[(x, i) for i, x in enumerate(q, start=1)]   # 인덱스 튜플로 저장(값, 인덱스)
  subQ=[q2.pop(0) for _ in range(N)]    # 화덕 크기만큼 피자를 올린다
  
  while (len(subQ) != 1) :
    temp=subQ.pop(0)
    num=temp[0]//2
    if num :		# 치즈가 덜 익었으면 다시 화덕에 넣기
      subQ.append((num, temp[1]))
    else:			# 그 다음 피자 올리기
      if q2:    # q2의 첫 번째
        tempQ=q2.pop(0)
        subQ.append((tempQ[0], tempQ[1]))		

  print(f"#{tc} {subQ[0][1]}")

 

위 코드와 다르게 일단 화덕에서 피자를 빼고 2로 나눈 후 값 num이 0이 아니면 subQ에 추가한다.

num이 0이면 리스트 q2에서 값을 빼서 subQ에 추가한다.

 

for t in range(int(input())) :
  n, m = list(map(int, input().split()))		# 화덕 크기, 피자 개수
  tmp=list(map(int, input().split()))			# 치즈
  cheese=[]
  for i in range(m):
    cheese.append([i+1, tmp[i]])    # 피자 넘버를 기억하기 위해서 인덱스와 데이터 값을 저장

  cQ=[]
  for i in range(n) :
    cQ.append(cheese.pop(0))		# 화덕의 크기만큼 피자 올리기

  idx=0
  while True :
    cQ[idx][1] = cQ[idx][1] //2
    if cQ[idx][1] == 0 :
      pizza_number=cQ[idx][0]
      if len(cheese) > 0 :			# 남은 피자가 있다면
        cQ[idx]=cheese.pop(0)
    idx=(idx+1)%n
    if sum(i[1] for i in cQ) == 0 : break # 피자 치즈가 하나도 안남아있을 때 탈출

  print("#{} {}". format(t+1, pizza_number))

 

리스트 cQ내의 리스트[1]이 모두 0이 되면 while문을 끝낸다.

위의 코드들과 로직은 같음.

반응형

'coding test' 카테고리의 다른 글

[파이썬] 5108. 숫자 추가  (0) 2021.01.29
[파이썬] 5102. 노드의 거리  (0) 2021.01.27
[파이썬] 5105. 미로의 거리  (0) 2021.01.25
[파이썬] 5097.회전  (0) 2021.01.25
[파이썬] 4881. 배열 최소 합  (0) 2021.01.20