Python | 대표값

crystal·2021년 9월 5일
0

Algorithm

목록 보기
6/8

대표값

1. 문제 🧐

N명의 학생의 수학점수가 주어집니다. N명의 학생들의 평균(소수 첫째자리 반올림)을 구하고, N명의 학생 중 평균에 가장 가까운 학생은 몇 번째 학생인지 출력하는 프로그램을 작성하세요.
평균과 가장 가까운 점수가 여러 개일 경우 먼저 점수가 높은 학생의 번호를 답으로 하고, 높은 점수를 가진 학생이 여러 명일 경우 그 중 학생번호가 빠른 학생의 번호를 답으로 합니다.

2. 입력

첫줄에 자연수 N(5<=N<=100)이 주어지고, 두 번째 줄에는 각 학생의 수학점수인 N개의 자연수가 주어집니다. 학생의 번호는 앞에서부터 1로 시작해서 N까지이다.

10
45 73 66 87 92 67 75 79 75 80


3. 출력

첫줄에 평균과 평균에 가장 가까운 학생의 번호를 출력한다.
평균은 소수 첫째 자리에서 반올림합니다.

74 7


4. 문제 풀이 핵심 point 🔍

솔직히 이 문제는 그냥 생각해서 풀기에는 조금 어려운 감이 없지 않아 있었던 것 같다 ㅋㅋㅋ ㅜㅠ

point 1. 학생점수와 평균과의 거리

10 => 학생 수 10명
45 73 66 87 92 67 75 79 75 80 => 학생의 점수
👉 평균이 74점으로 평균과 가장 가까운 점수는 73(2번), 75(7번), 75(9번)입니다. 여기서 점수가 높은 75(7번), 75(9번)이 답이 될 수 있고, 75점이 두명이므로 학생번호가 빠른 7번이 답이 됩니다

⭐ 문제의 핵심 포인트는 절대값 | 학생 점수-평균 |이다. 즉 평균과 학생 점수와의 거리가 중요하다.

  1. 평균과 학생 점수와의 거리가 클수록, 평균과 가깝지 않다.
  2. 평균과 학생 점수와의 거리가 짧을수록 평균과 가까운 점수이다.

point 2. |평균-학생점수|의 최소값 구하기

⭐ 최소값 구하는 로직은 앞으로도 계속 쓰인다.

min=float('inf') # 최소값 
min_idx = 0 # 최소값 인덱스
for idx, n in enumerate(num):
    if n < min:
        min=n
        min_idx=idx

반대로 하면 최대값 구하는 로직이고, == 으로 바꾸면 같은 값 구하는 로직이 된다.

위 로직에서 |평균-학생점수| 가 추가 되었다.

ave = round(sum(a)/n)
min = 2147000000 # int 4바이트에서 가장 큰 수 

for idx, x in enumerate(a) : 
	tmp=abs(x-ave) # (학생 점수 - 평균)의 절대값, 학생점수와 평균과의 거리 
    
    # |학생 점수 - 평균| 의 최소값 구하기 = 평균과 가장 가까운 값
    if tmp < min: 
    	min=tmp
        score=x #학생점수 최소값 저장할 변수
    	res=idx+1 # 인덱스를 저장할 변수, 1번부터 시작해야하므로 

5. 코드 💻

1) 내 풀이

# N = int(input())
# num = list(map(int, input().split()))
N = 10
num = [45,73,66,87,92,67,75,79,75,80]

sum = 0

# 합 구하기
for n in num:
    sum += n

# 평균 구하기 - 반올림해야함
avg = round(sum / len(num))

min=float('inf')
for idx, n in enumerate(num):
    dis = abs(n-avg)
    if dis < min:
        min=dis
        score=n  # 제일 차이가 작은 학생점수
        min_idx=idx+1 # 제일 차이가 작은 인덱스

    elif dis == min:
        if n > score:
            score=n
            min_idx=idx+1

print(avg,min_idx)

2) 모범 답안

N = int(input())
a = list(map(int, input().split()))

ave = round(sum(a)/n)
min = 2147000000 # int 4바이트에서 가장 큰 수 

for idx, x in enumerate(a) : 
	tmp=abs(x-ave) # (학생 점수 - 평균)의 절대값, 학생점수와 평균과의 거리 
    
    # |학생 점수 - 평균| 의 최소값 구하기 = 평균과 가장 가까운 값
    if tmp < min: 
    	min=tmp
        score=x #학생점수 최소값 저장할 변수
    	res=idx+1 # 인덱스를 저장할 변수, 1번부터 시작해야하므로 
    
    # 평균과 가장 가까운 값 중에서 73, 75 둘 다 평균 74와 거리가 1
    elif tmp == min: 
    	if x > score: # 학생점수 최대값 구하기 : 75 > 73
            score=x # 학생점수 최대값 75 저장
            res=idx+1 # 학생점수 최대값 인덱스

print(ave, res)
   




6. 파이썬 문법 기억해야 할 것 🤩

1. sum() 함수

sum() : 리스트 내의 모든 수를 더해주는 함수

for문으로 일일이 리스트 내의 수를 다 더할 필요가 없었다.
이렇게 쉬운 방법이 있는데 문제풀 때는 왜 생각이 안 나는지 🤣🤣

2. round() 함수

round(숫자) : 소수 첫째자리부터 반올림 해주는 함수
round(숫자, 2) : 소수 셋째자리부터 반올림 해주는 함수
round(숫자, -1) : 일의 자리부터 반올림 해주는 함수

3. // : 몫

// : 나눗셈할 때 몫을 구하는 것

문제에는 안 나왔지만, 내가 안까먹으려고 다시 써봤다.

4. enumerate() 함수

enumerate() : for idx, x in enumerate(a)

  1. idx : a리스트의 인덱스
  2. x : a리스트 안의 값
    => 최대값, 최소값 구할 때 유용하게 쓰임..

5. abs() 함수 : 절대값

abs() : 절대값 함수

출처 : 한국정보올림피아드
profile
어제보다 더 나은 오늘의 내가 되자 ✧ʕ̢̣̣̣̣̩̩̩̩·͡˔·ོɁ̡̣̣̣̣̩̩̩̩✧ 

0개의 댓글