문제: https://www.acmicpc.net/problem/1546
1546번: 평균
첫째 줄에 시험 본 과목의 개수 N이 주어진다. 이 값은 1000보다 작거나 같다. 둘째 줄에 세준이의 현재 성적이 주어진다. 이 값은 100보다 작거나 같은 음이 아닌 정수이고, 적어도 하나의 값은 0보
www.acmicpc.net
이 문제는 처음에 봤을 때 이해가 되지 않는 문제였다.
필자는 책에 있는 문제 분석하기 파트를 읽어도 헤맸는데,
그 이유가 점수를 계산하는 방식에서 점수/최댓값*100을 하면 0아닌가???
이러면서 예제 출력을 이해하지 못했었다.
근데 알고리즘 단톡방에 계신 분들 중 double형으로 생각해보라고 조언해주신 분 덕분에 한번에 이해가 되었다.
문제에서 예시를 든 수학점수를 계산하는 것은 50/70*100인데, 이걸 int형으로 계산해보면 0으로 나올 것이다.
하지만, double 형으로 바꾸면 71.43으로 결과가 나오는 것을 보면,
이 값은 0.7143xxx 이런 식으로 나오는 것을 알 수 있다.
그리고 평균을 구하는 식은 각 (과목의 점수들의 합/과목수) 이건데,
여기에선 각 과목의 점수들(원점수)을 각각 A,B,C라고 보고, 가장 높은 점수를 max라 생각해보자.
이런식으로 계산이 되는데, 부끄럽지만 필자는 엄청난 수포자였기 때문에 책에 있는 (A+B+C)*100/max/3 이게 한눈에 안들어와서 직접 해체했던 기억이 있다. 필자는 (A+B+C)*100/3*max 이렇게 되는거 아닌가 생각을 했었는데,
괄호를 (A+B+C)*100/(3*max) 이렇게 하면 맞는걸 확인할 수 있다.
자 그럼 이제 코딩으로 넘어와보자. 코딩으로는 2개의 문제가 있다.
① 최대값 구하기 - Arrays 클래스에 있는 sort 함수를 써도 되고, for문으로 찾아도 된다.
② 배열에 변수를 저장하고 합을 구하기
1번 같은 경우에는 2가지의 해결방법이 있는데, sort버전과 for문 버전의 결과와 코딩은 밑에서 확인할 수 있다.
2번 같은 경우에는 입력받는 것을 점수를 저장하는 배열에 넣으면 되는데 Scanner를 이용한다면 scores[i] = sc.nextInt(); 로 쓸 수 있겠다.
따라서 코드를 살펴보자면,
//버전 1. for문 사용해서 최대값 찾기
import java.io.*;
import java.util.*;
public class BOJ_1546 {
public static void main(String[] args) throws IOException{
// TODO 백준 1546
//입력을 빨리 받기 위해서 BufferedReader 클래스를 사용해준다.
//BufferedReader 클래스로 이용한 입력은 한 줄 단위로 읽기 때문에 문자열 파싱이 필요함
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
//N은 과목 수, sum은 점수의 총합(가공x), max는 점수의 최대값을 저장할 변수이다.
//scores 배열은 점수들을 저장할 배열이다.
int N = Integer.parseInt(st.nextToken());
int sum = 0, max = 0;
int[] scores = new int[N];
//점수 배열에 입력받은 점수들을 저장해주고,
//그 점수들을 다 더해준다.
//만약에 max변수가 scores[i] 보다 작으면 max에 scores[i]를 저장해준다.
st = new StringTokenizer(br.readLine());
for(int i=0; i<N; i++) {
scores[i] = Integer.parseInt(st.nextToken());
sum += scores[i];
if(max < scores[i]) {
max = scores[i];
}
}
//평균 출력
System.out.println((double)sum*100/max/N);
}
}
2번째 코드.
//버전 2. Arrays.sort()를 사용한 코드
import java.io.*;
import java.util.*;
public class BOJ_1546_ver2 {
public static void main(String[] args) throws IOException{
// TODO 백준 1546
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int sum = 0, max = 0;
int[] scores = new int[N];
st = new StringTokenizer(br.readLine());
for(int i=0; i<N; i++) {
scores[i] = Integer.parseInt(st.nextToken());
sum += scores[i];
}
//배열을 오름차순으로 정렬해주고 최대값을 저장해준다.
Arrays.sort(scores);
max = scores[N-1];
//저장된 최대값을 출력한다.
System.out.println((double)sum*100/max/N);
}
}
sort로 한 것과 for문으로 한 것의 메모리 차이와 시간
어? if문이 줄었는데, 왜 sort가 더 메모리와 시간을 더 잡아먹지? 에 대해서 궁금할 수 있다.
이건 필자가 JAVA_travel에서 차후에 다룰 내용이긴 한데,
sort는 왜 메모리를 좀 더 잡아먹을까? 에 대한 탐구를 할 예정이다.
'☕JAVA > 👩💻BOJ(백준)' 카테고리의 다른 글
[투 포인터, JAVA] 백준 - 2467 (0) | 2022.09.19 |
---|---|
[구간합, JAVA] 백준 - 10986 (0) | 2022.08.20 |
[구간합, JAVA] 백준 - 11660 (0) | 2022.08.17 |
[구간합, JAVA]백준 - 11659번 (0) | 2022.08.16 |
[배열, JAVA] 백준 - 11720번 (0) | 2022.08.16 |