문제풀이/일일연습문제

[array]99클럽 코테 스터디 8일차 TIL + 백준/Bronze/25593. 근무 지옥에 빠진 푸앙이 (Small)

Mo_bi!e 2024. 11. 5. 08:46

문제 설명

 

군대에 간 푸앙이는 4교대 근무를 서게 된다. 근무 시간대는 08:00~12:00, 12:00~18:00, 18:00~22:00, 22:00~08:00 으로 각각 4, 6, 4, 10시간의 근무로 구성되어 있다.

푸앙이와 동기들은 근무 시간이 최대한 공평하게 배분되기를 원한다. 그래서 근무표 전체에서 각 인원의 근무 시간이 12시간 이하로 차이 나게 해서 최대 50주 치 근무표를 짜려고 한다.

푸앙이는 원래 똑똑해서 이 정도는 한눈에 계산이 가능했지만 어째서인지 푸앙이는 계산이 불가능해졌다. 푸앙이를 위해서 대신 근무표가 공평한지 계산해주자.

 

 

### 입력

첫 번째 줄에 주의 개수인 N이 입력된다. (1≤N≤50)

둘째 줄부터 근무표가 주어진다. 각 주는 4개의 줄로 표현되며, 그중 첫째 줄은 각 날의 08:00~12:00에 근무하는 사람의 이름 또는 '-', 둘째 줄은 12:00~18:00, 셋째 줄은 18:00~22:00, 넷째 줄은 22:00~08:00을 나타낸다. '-'는 근무자가 없음을 의미한다. 근무자의 이름은 모두 알파벳 소문자로 이루어져 있고 20글자를 넘지 않는다.

각 날에는 4개의 시간대에 모두 근무자가 있거나 모두 근무자가 없다. 예를 들어 12:00~18:00에만 근무자가 있는 날은 없다.

근무표에 적히지 않은 근무자는 없으며, 근무자 수는 최대 100명이다.

 

 

### 출력

근무표가 공평하면 “Yes”를 아니면 “No”를 출력한다. 단, 아무도 근무하지 않을 경우 공평한 것으로 간주한다.

 

 

<내 코드>

import sys
from collections import defaultdict

# 1. 입력
N = int(sys.stdin.readline())

work_dict = defaultdict(int)
for i in range(4 * N):
    count = i % 4

    daily_workers = sys.stdin.readline().split()
    daily_workers_ = [worker for worker in daily_workers if worker != '-']
    # print(daily_workers_)

    if count == 0 or count == 2:
        for worker in daily_workers_:
            work_dict[worker] += 4
    elif count == 1 :
        for worker in daily_workers_:
            work_dict[worker] += 6
    elif count == 3:
        for worker in daily_workers_:
            work_dict[worker] += 10


# 2. dict 비교
# sorted_work_dict = sorted(work_dict.items(), key = lambda  item:item[1]) -> 필요없음
# print(sorted_work_dict)

# min = sorted_work_dict[0][1]
# max = sorted_work_dict[-1][1]

# min_hours = min(work_dict.values())
# max_hours = max(work_dict.values())

# differ = max_hours - min_hours
# print(differ)

if work_dict:
    min_hours = min(work_dict.values())
    max_hours = max(work_dict.values())
    differ = max_hours - min_hours
    if differ <= 12:
        sys.stdout.write("Yes")
        # print("Yes")
    else :
        sys.stdout.write("No")
        # print("No")
else :
    sys.stdout.write("Yes")
    # print("Yes")

2중 for 문을 피하려고 했는데 어쩔수 없이 이 방식으로 풀어버린 방식임

출력은 sys.stdout.write 를 써보았음

 

-반성

0. 나머지로 나오는 count 값이 나누려는 값 4보다 작은 i라도 그 값이 나올 수 있음을 기억해야함

 

1. 리스트 컨프리헨션으로 일부 내용을 바꿀수 있다는것을 자주 잊어버림

daily_workers_ = [worker for worker in daily_workers if worker != '-']

이렇게 하면 '-'를 제외하고 손쉽게 가능함

 

2. 정렬을 해도되지만, 딕셔너리의 values 에 대해서 min, max 함수 작동이 가능함

 

<모범사례>

import sys
from collections import defaultdict

# 입력 처리
N = int(sys.stdin.readline().strip())

# 각 근무자의 총 근무 시간을 저장할 딕셔너리
work_hours = defaultdict(int)
# 각 시간대별 근무 시간을 리스트로 저장
shift_hours = [4, 6, 4, 10] #포인트1

# 근무 시간 누적
for i in range(4 * N):
    # 근무자 이름 리스트, '-'는 필터링
    workers = sys.stdin.readline().strip().split()
    for worker in workers:
        if worker != '-': #포인트2
            work_hours[worker] += shift_hours[i % 4] # 포인트1

# 최소, 최대 근무 시간 차이 계산
if work_hours:
    min_hours = min(work_hours.values())
    max_hours = max(work_hours.values())
    print("Yes" if max_hours - min_hours <= 12 else "No") # 포인트3
else:
    print("Yes")

shift_hours 라는 리스트를 지정해서 인덱스를 돌려가면서 쉽게 가능함

이렇게 하면 코드 중복을 막을 수 있음

 

 

아래쪽에 조건부 출력으로 쉽게 가능

 

 

<보충학습>

1. 4개의 조건을 리스트에 담아서 인덱스로 돌려가면서 가능함