문제
대학생 새내기들의 90%는 자신이 반에서 평균은 넘는다고 생각한다. 당신은 그들에게 슬픈 진실을 알려줘야 한다.
입력
첫째 줄에는 테스트 케이스의 개수 C가 주어진다.
둘째 줄부터 각 테스트 케이스마다 학생의 수 N(1 ≤ N ≤ 1000, N은 정수)이 첫 수로 주어지고, 이어서 N명의 점수가 주어진다. 점수는 0보다 크거나 같고, 100보다 작거나 같은 정수이다.
출력
각 케이스마다 한 줄씩 평균을 넘는 학생들의 비율을 반올림하여 소수점 셋째 자리까지 출력한다. 정답과 출력값의 절대/상대 오차는 10-3이하이면 정답이다.
C = int(input())
for _ in range(C):
data = list(map(int, input().split()))
N = data[0]
scores = data[1:]
avg = sum(scores) / N
count = 0
for s in scores:
if s > avg:
count += 1
rate = (count / N) * 100
print(f"{rate:.3f}%")
1. 테스트 케이스의 개수 C를 입력받아 정수형태로 저장한다.
2. list를 저장할 변수 data를 만들고 입력받은 것을 공백을 기준으로 나누고 정수형으로 변환하여 list에 저장한다.
3. data의 0번째 인덱스를 학생의 수 N으로 지정하고 1번째인덱스부터 끝까지는 scores라고 지정한다.
4. 평균은 scores의 총합을 학생 수 N으로 나눈 것이다.
5. 평균을 넘은 학생 수를 저장할 변수 count을 0으로 초기화한다.
6. 만일 점수 s가 평균보다 크면 count가 1 증가한다.
7. 평균을 넘는 학생들의 비율을 저장할 변수 rate는 count를 학생 수 N으로 나누고 100을 곱한 수이다.
8. 반올림하여 소수점 이하 3자리까지 표시한 rate를 출력한다.
+) f"..." : f-string(포매팅 문자열) ; 문자열 안에 { }를 써서 변수나 표현식의 값을 바로 넣는 방법
+) {rate: .3f} 에서
rate → 출력할 변수 이름
: → 포맷 지정 시작
.3f → 실수 형식으로 소수점 이하 3자리까지 표시하며 자동으로 반올림 됨

문제
N개의 수 A1, A2, ..., AN과 L이 주어진다.
Di = Ai-L+1 ~ Ai 중의 최솟값이라고 할 때, D에 저장된 수를 출력하는 프로그램을 작성하시오. 이때, i ≤ 0 인 Ai는 무시하고 D를 구해야 한다.
입력
첫째 줄에 N과 L이 주어진다. (1 ≤ L ≤ N ≤ 5,000,000)
둘째 줄에는 N개의 수 Ai가 주어진다. (-109 ≤ Ai ≤ 109)
출력
첫째 줄에 Di를 공백으로 구분하여 순서대로 출력한다.
import sys
from collections import deque
input = sys.stdin.readline
write = sys.stdout.write
N, L = map(int, input().split())
A = list(map(int, input().split()))
dq = deque()
for i in range(N):
# 덱의 뒤에서 A[i]보다 큰 값 제거
while dq and A[dq[-1]] > A[i]:
dq.pop()
dq.append(i)
# 윈도우 범위 벗어난 인덱스 제거
if dq[0] <= i - L:
dq.popleft()
# 현재 최소값 출력 (공백으로 구분)
write(str(A[dq[0]]) + ' ')
1. 표준입출력 긴 스트림 처리용 ( sys.stdin.readline , sys.stdout.write를 쓰려면 필요 )
2. from collections import deque는 양쪽에서 O(1){시간복잡도, 입력크기에 상관없이 일정 시간}로 push/pop 가능한
덱(deque)을 쓰기 위한것. 슬라이딩 윈도우의
최소를 유지할 때 최적
3. input()보다 훨씬 빠른 입력 함수로 대체 ( 끝에 \n이 붙어 필요할 때 .strip()을 사용해야하지만 여기서는 split()으로 바로
처리해서 괜찮음)
4. print()보다 빠른 출력 함수로 대체. 매번 호출해도 오버헤드가 작아 대량 출력 시 필수적
5. 입력받은 것을 공백을 기준으로 나눠 int형으로 변환해 각각 N(원소 수)과 L(윈도우 크기)에 저장
6. N개의 정수들을 한번에 리스트로 읽음
7. 인덱스를 저장할 빈 덱을 초기화. (덱에는 값이 아니라 인덱스를 저장하는게 핵심-윈도우 범위 체크를 쉽게 하기 위해)
8. 덱의 맨 뒤부터 현재 값 A[i]보다 큰 값들을 전부 제거 (뒤의 큰 값들은 앞으로 나올 A[i]보다 항상 크므로 A[i]가 앞에 있으면
그 큰 값은 최소 후보가 될 수 없음)
9. 현재 인덱스 i를 덱 뒤에 추가 (인덱스는 항상 증가하므로 덱 내에서 인덱스는 오름차순 유지)
10. 현재 윈도우는 [i-L+1, ... , i]이므로 인덱스가 i-L 이하면 윈도우에서 벗어난 것 (덱의 맨 앞이 가장 작은 인덱스 원소이므로 윈도우를
벗어나면 앞에서 하나 제거)
11. 덱의 맨 앞 dq[0]는 현재 윈도우의 최소값의 인덱스이므로 A[dq[0]]를 출력 + 공백으로 구분해서 바로 출력
+) deque는 double-ended queue(양쪽 끝에서 뽑고 넣을 수 있는 큐)의 줄임말
슬라이딩 윈도우: 연속된 일정 길이의 구간(Window)를 만들어서 배열이나 문자열 같은 자료구조를 한칸씩 이동시키며 처리하는 기법
+) print()보다 이 문제에서는 sys.stdout.write()쓰는게 효율적 (속도, 메모리 측면에서)

'SWLUG(2025) > Algorithm' 카테고리의 다른 글
| [2학기 6주차] 너의 이름은 몇 점이니?, 히든 넘버 (0) | 2025.11.09 |
|---|---|
| [2학기 5주차] 이상한 곱셈, Shares (0) | 2025.11.05 |
| [2학기 3주차] 수 정렬하기 3, 수열 (0) | 2025.09.30 |
| [2학기 2주차] 숫자의 합, 바구니 뒤집기 (0) | 2025.09.21 |
| [2학기 1주차] 새싹, 공 넣기 (0) | 2025.09.15 |