HOONDOC

[백준]1546 평균 - Java/자바 본문

문제 풀이/BAEKJOON

[백준]1546 평균 - Java/자바

HOONDOC 2022. 12. 28. 22:08

1546번: 평균

풀이

  • 메모리 14644KB, 시간 156ms
  • 수식을 일반화하지 않고 주어진대로 구현했다면 시간초과가 났을 것 같다.
  • 공식이 주어진 상황에서는 일반화가 가능한지, 수식 단축이 가능한지 살펴볼 것.
  • 출력 형식이 실수형이므로 float내지는 double을 쓴다.이 문제는 평균 값이므로 float만 써도 충분할듯
  • 범위 문제로 틀릴까봐 그냥 double만 썼는데
import java.util.Scanner;

/*
 * TAG: 수학, 수식
 * A B C (A가 최고점) -> A/A*100, B/A*100, C/A*100
 * 수식이 (모든 값의 합/최고점)*100으로 수렴
 */
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int bestScr = 0; // 최고점
		double sum = 0; // 모든 값의 합
		
		for(int i = 0; i<N; i++) {
			int currentScr = sc.nextInt();
			if(bestScr < currentScr) bestScr = currentScr;
			sum += currentScr;
		}
		
		System.out.println(sum/bestScr*100/N);
		sc.close();
	}
}

코드 리뷰

  • 메모리와 시간이 모두 내 풀이보다 두 배 가까이 크다.
  • 수식의 일반화가 이루어지지 않아서 연산량이 증가한 것으로 보인다.
  • float을 사용한 건 좋았다고 생각한다.

💡 풀이자 : minkang313, 메모리 : 20164KB, 시간 280ms

import java.util.Scanner;

public class Main{

	public static void main(String[] args){

		Scanner scan = new Scanner(System.in);
		
		int count = scan.nextInt();
		float[] scoreArr = new float[count];
		int maxScore = 0;
		float sum = 0;
		
		for(int i=0; i<count; i++){
			int score = scan.nextInt();
			scoreArr[i] = score;
			if(score > maxScore){
				maxScore = score;
			}
		}
		for(int j=0; j<count; j++){
			scoreArr[j] = scoreArr[j] / maxScore * 100;
		}

		for(float score : scoreArr){
			sum += score;
		}
		System.out.println(sum / count);
	
	}

}

 

  • Scanner가 아닌 BufferedReader와 StringTokenizer를 사용해서 시간과 메모리가 단축됐다.
  • 기본적인 로직과 코드 구성은 일치한다.

💡 풀이자 : qushe8r 메모리 : 14340KB, 시간 : 128ms

import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st;
        st = new StringTokenizer(br.readLine());
        
        int num = Integer.parseInt(st.nextToken());
        st = new StringTokenizer(br.readLine());

        int[] arr = new int[num];
        for (int i = 0; i < num; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }
        
        long max = 0;
        double sum = 0;

        for (int i : arr) {
            sum += i;
            if (i > max) max = i;
        }
        
        System.out.println(sum * 100 / max / num);
    }
}

 

  • 메모리 사용과 시간이 가장 크게 소요된 풀이 코드였다.
  • 수식을 일반화하지 않아 연산량이 증가한 것과, Arrays.sort() 사용이 원인으로 보인다.최댓값만 필요하므로 모든 값을 정렬할 필요는 없다. if문을 사용하는게 더 효율적인 케이스다.
  • 정렬 함수를 사용한 이유로 최댓값을 찾으려 한 것 같은데,

💡 풀이자 : noble9915 메모리 : 25136KB, 시간 : 392ms

import java.util.Scanner;
import java.util.Arrays;

public class Main{
    public static void main(String args[]){
        Scanner scan = new Scanner(System.in);
        
        double arr[] = new double[scan.nextInt()];
        
        for(int i =0; i <arr.length; i++){
            arr[i] = scan.nextDouble();
        }
        scan.close();
        
        double sum =0;
        Arrays.sort(arr);
        
        for(int i =0; i <arr.length; i++){
            sum += ((arr[i]/arr[arr.length-1]) * 100);
        }
        System.out.print(sum/arr.length);
            
    }
}

Conclusion

  • 수식을 세우고 구현하는게 문제일 경우 수식을 줄일 수 있는지 체크하기
  • 값의 범위가 어디까지인지 생각해보고 그에 맞는 자료형을 사용하기