[백준/프로그래머스] 20주차 스터디 (10825 국영수, 18310 안테나, 1715 카드 정렬하기 / 42889 실패율)

새싹·2022년 2월 9일
0

알고리즘

목록 보기
33/49

10825 국영수

📌문제 링크

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

💡 문제 풀이

(책 코드를 참고했습니다)
파이썬의 sort(key)를 사용해서 풀 수 있는 문제다.
sort(key)는 아이템의 순서대로 우선순위를 부여해 정렬하며, -를 붙이면 내림차순으로 정렬한다.

arr.sort(key=lambda x : (x[0], -x[1]))

위 코드는 첫 번째 인자를 기준으로 오름차순으로 먼저 정렬하고, 그 다음 두 번째 인자를 기준으로 내림차순으로 정리한다.

📋코드

# 10825 국영수
import sys
n = int(input())
student = []

for i in range(n):
    student.append(sys.stdin.readline().split())

'''
x[0]: 이름, x[1]: 국어 점수, x[2]: 영어 점수, x[3]: 수학 점수
1. 국어 점수가 감소하는 순서로
2. 국어 점수가 같으면 영어 점수가 증가하는 순서로
3. 국어 점수와 영어 점수가 같으면 수학 점수가 감소하는 순서로
4. 모든 점수가 같으면 이름이 사전 순으로 증가하는 순서로 
5. (단, 아스키 코드에서 대문자는 소문자보다 작으므로 사전순으로 앞에 온다.)
'''
student.sort(key=lambda x: (-int(x[1]), int(x[2]), -int(x[3]), x[0]))

for s in student:
    print(s[0])

18310 안테나

📌문제 링크

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

💡 문제 풀이

그냥 정렬하고 나서
제일... 가운데에 있는 집에 설치하면 되는 거 아닌가?
정말 이렇게 쉽게 푸는 게 맞나? 싶어서 책 코드를 봤다
정말이었다

📋코드

# 18310 안테나
import sys
n = int(input())
home = list(map(int, sys.stdin.readline().split()))
home.sort()

# 가운데에 위치한 집에 안테나 설치
# 답으로 여러 개가 나올 때, 몫 나누기 // 를 사용하면 자동으로 작은 값 나옴
print(home[(n-1) // 2])

1715 카드 정렬하기

📌문제 링크

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

💡 문제 풀이

카드의 개수가 적은 묶음 순서대로 비교해 나가는 게 가장 효율정인 방법이니 heapq를 사용하면 되겠다고 생각했다.
생각나는 대로 풀었는데 이전 코드를 확인해보니 전에 구글링해서 풀었던 답이랑 거의 똑같이 풀어서 뿌듯했다!

📋코드

# 1715 카드 정렬하기 (두 번째 풀이)
import heapq
n = int(input())
card = []

for i in range(n):
    card.append(int(input()))

result = 0
heapq.heapify(card)

while len(card) > 1:
    # 가장 작은 값 2개 pop
    n1 = heapq.heappop(card)
    n2 = heapq.heappop(card)

    # 비교 횟수 (두 값을 더한 값) 누적
    result += n1+n2

    # 카드 더미 다시 push
    heapq.heappush(card, n1+n2)

print(result)

42889 실패율

📌문제 링크

https://programmers.co.kr/learn/courses/30/lessons/42889

💡 문제 풀이

먼저 stages를 정렬하고, 스테이지 1번부터 N+1번 순서로 반복을 돌며 count(i)로 도달했지만 클리어하지 못한 플레이어의 수를 센다.
그 다음 스테이지에 도달한 플레이어의 수는 전체 사용자 수(len(stages))에서 클리어하지 못한 플레이어의 수를 누적해서 빼가며 구한다.
-> 이 때 꼭 도달한 플레이어의 수가 0명일 경우를 따로 계산해야 한다!! 이거 안 해줘서 런타임 에러나는 테스트 케이스들이 있었다ㅠ

(실패율, 스테이지 번호) 순서로 배열에 넣고, 다시 배열을 정렬한다.
이 때, 먼저 실패율이 큰 순서로 정렬하고 실패율이 같을 경우 스테이지 번호가 작은 순서로 정렬한다.
-> 실패율을 첫 번째 인자로 넣어서 그냥 reverse=True 옵션만 넣고 정렬했는데, 스테이지 번호가 작은 순서대로 안 나와서 틀렸었다

count를 계속 쓰는 게 시간복잡도에 안 좋지 않을까?라고 생각했는데
달리 풀 방법도 생각 안 나고 어차피 효율성 테스트 없으니까 그냥 풀었다

📋코드

# 42889 실패율

def solution(N, stages):
    failure = []
    stages.sort()
    # 스테이지에 도달한 플레이어 수
    reached = len(stages)

    for i in range(1, N+1):
        # 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수
        fail_num = stages.count(i)

        # 도달한 플레이어가 없을 때
        if reached == 0:
            failure.append((0, i))
        else:
            failure.append((fail_num/reached, i))
        
        # 다음 스테이지에 도달한 플레이어 수 계산
        reached -= fail_num
    
    # 실패율이 높은 순서대로, 실패율이 같다면 스테이지 번호가 작은 순서대로 정렬
    failure.sort(key=lambda x: (-x[0], x[1]))
    
    # 스테이지 번호만 따로 배열에 넣어 리턴
    answer = []
    for f in failure:
        answer.append(f[1])
    return answer

0개의 댓글