[백준] 4344번 : 평균은 넘겠지 - JAVA [자바]
https://www.acmicpc.net/problem/4344
- 문제
매우 간단한 문제다!
※ 주의할 점
- 출력은 반드시 소수점 셋째자리까지 출력한다.
- 각 테스트 케이스의 첫 번째 수는 해당 케이스의 입력 개수다.
- 평균을 넘기는(초과하는) 학생의 비율을 %로 출력해야한다.
- 2가지 풀이방법을 제시한다.
배열을 이용하여 Scanner 로 입력받는 방법, BufferedReader 로 입력받는 방법을 통해 두 가지 케이스를 보여줄 것이다.
- 풀이
- 방법 1
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] arr;
int testcase = in.nextInt();
for(int i = 0 ; i < testcase ; i++) {
int N = in.nextInt(); //학생 수
arr = new int[N];
double sum = 0; // 성적 누적 합 변수
// 성적 입력부분
for(int j = 0 ; j < N ; j++) {
int val = in.nextInt(); // 성적 입력
arr[j] = val;
sum += val; // 성적 누적 합
}
double mean = (sum / N) ;
double count = 0; // 평균 넘는 학생 수 변수
// 평균 넘는 학생 비율 찾기
for(int j = 0 ; j < N ; j++) {
if(arr[j] > mean) {
count++;
}
}
System.out.printf("%.3f%%\n",(count/N)*100);
}
in.close();
}
}
알고리즘 자체는 설명할 것이 많이 없다.
먼저 테스트 케이스 만큼 반복문을 돌리면서 배열에 성적을 저장함과 동시에 누적 합을 같이 구해준다.
그런 뒤 평균 성적을 구하여 배열에 저장된 성적들과 비교한 뒤 몇 명의 학생이 평균보다 높은지 세어주면 된다.
참고로 소수점 셋째자리까지 출력하기 위해서는 printf() 를 써서 %.3f 으로 출력 포멧을 지정해주어야 한다.
또한 printf 에서 "%" 라는 문자를 출력을 하려면 %% 로 적어주어야 % 라는 문자가 출력되는 것을 알아두자.
- 방법 2
물론 BufferedReader 로도 가능하다.
단, 입력과정에서 한 줄을 통째로 읽기 때문에 읽어들인 문자열을 StringTokenizer을 통해 공백을 기준으로 분리해주어야 한다.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int[] arr;
int testcase = Integer.parseInt(br.readLine());
StringTokenizer st;
for(int i = 0 ; i < testcase ; i++) {
st = new StringTokenizer(br.readLine()," "); // 학생 수 및 성적 입력
int N = Integer.parseInt(st.nextToken()); //학생 수
arr = new int[N];
double sum = 0; // 성적 누적 합 변수
// 성적 입력부분
for(int j = 0 ; j < N ; j++) {
int val = Integer.parseInt(st.nextToken()); // 성적 저장
arr[j] = val;
sum += val; // 성적 누적 합
}
double mean = (sum / N) ;
double count = 0; // 평균 넘는 학생 수 변수
// 평균 넘는 학생 비율 찾기
for(int j = 0 ; j < N ; j++) {
if(arr[j] > mean) {
count++;
}
}
System.out.printf("%.3f%%\n",(count/N)*100);
}
}
}
보면 알겠지만 그렇게 변경된 것이 없다.
다만 BufferedReader.readLine() 자체가 한 줄을 통째로 읽기 때문에 이중 for문의 첫번 째 for문에서는 입력이 아닌, StringTokenizer 에 공백을 기준으로 구분 된 토큰을 반환시켜 배열에 저장시킨다.
그리고 위의 코드를 좀 더 정리하면 더 성능을 좋게 만들 수 있다.
※ 힌트
- 출력 방법 변경
- 변수 선언 및 캐스팅 최소화
- 성능
위에서 부터 순서대로
채점 번호 : 31088686 - BufferedReader + 배열
채점 번호 : 31088677 - Scanner + 배열
입력의 경우는 확실히 Scanner 보다는 BufferedReader 가 빠른 걸 볼 수 있다.
- 정리
이 문제를 끝으로 1차원 배열 카테고리가 끝이 났다.
그래도 배열 카테고리인 만큼 배열에 대해 마지막으로 정리하고자 한다.
배열을 사용하면 여러모로 좋은 점이 있다.
장점으로는
- 메모리에 연속적으로 연결되어 할당하기 때문에 접근 속도가 빠르다. 즉 색인 속도가 빠르다는 것이다.
- 참조를 위한 추가적인 메모리 할당을 필요로 하지 않는다.
이정도가 있겠다. 물론 단점도 있다.
- 자료를 삭제 또는 삽입할 때 다른 데이터들을 밀어내거나 당겨와야하기 때문에 배열의 크기가 커질수록 비효율적이다.
- 배열의 크기는 불변이기 때문에 메모리가 낭비 될 수 있고, 또는 데이터는 많으나 배열에 다 넣지 못할 수도 있다.
이정도만 알고가도 될 것 같다. 위의 여러 장단점에 따라 배열이 아닌 연결리스트 등 많은 형태가 새로 나타나게 되는데 이는 나중에 기회가 되면 포스팅 해보기로 하겠다.
'JAVA - 백준 [BAEK JOON] > 1차원 배열' 카테고리의 다른 글
[백준] 8958번 : OX퀴즈 - JAVA [자바] (13) | 2020.03.09 |
---|---|
[백준] 1546번 : 평균 - JAVA [자바] (20) | 2020.03.02 |
[백준] 3052번 : 나머지 - JAVA [자바] (36) | 2020.03.02 |
[백준] 2562번 : 최댓값 - JAVA [자바] (35) | 2020.02.27 |
[백준] 10818번 : 최소, 최대 - JAVA [자바] (85) | 2020.02.27 |