본문 바로가기
코딩 문제/백준 [ Java ]

[ 백준 2108 / Java ] 통계학

by CODESIGN 2022. 1. 26.

https://www.acmicpc.net/problem/2108

 

2108번: 통계학

첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그 다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.

www.acmicpc.net

 

 

문제


수를 처리하는 것은 통계학에서 상당히 중요한 일이다. 통계학에서 N개의 수를 대표하는 기본 통계 값에는 다음과 같은 것들이 있다. 단, N은 홀수라고 가정하자.

  1. 산술평균 : N개의 수들의 합을 N으로 나눈 값
  2. 중앙값 : N개의 수들을 증가하는 순서로 나열했을 경우 그 중앙에 위치하는 값
  3. 최빈값 : N개의 수들 중 가장 많이 나타나는 값 (주어진 값 중에서 가장 자주 나타나는 값이다.)
  4. 범위 : N개의 수들 중 최댓값과 최솟값의 차이

N개의 수가 주어졌을 때, 네 가지 기본 통계 값을 구하는 프로그램을 작성하시오.

 

 

입력


첫째 줄에 수의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 단, N은 홀수이다. 그다음 N개의 줄에는 정수들이 주어진다. 입력되는 정수의 절댓값은 4,000을 넘지 않는다.

 

 

출력


첫째 줄에는 산술평균을 출력한다. 소수점 이하 첫째 자리에서 반올림한 값을 출력한다.

둘째 줄에는 중앙값을 출력한다.

셋째 줄에는 최빈값을 출력한다. 여러 개 있을 때에는 최빈값 중 두 번째로 작은 값을 출력한다.

넷째 줄에는 범위를 출력한다.

 

 

예제 입력 1 복사


5
1
3
8
-2
2

 

 

예제 출력 1 복사


2
2
1
10

 

 

예제 입력 2 복사


1
4000

 

예제 출력 2 복사


4000
4000
4000
0

 

NOTE 

Math.ceil

int에서 사용하면 정수가 나온다. 하지만 double에 사용하면 소수점이 발생하여 정상적으로 ceil을 사용할 수 있다.

 

자바에서 쓰는 Math 클래스에는 기본적으로 3가지가 있다:

Math.floor 내림 (floor)

Math.ceil 올림 (ceiling)

Math.round 반올림 round)

 

위 3가지는 소수점을 내림/올린/반올림해서 정수 .0형태의 double을 반환한다. 


 

 

풀이


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import java.util.*;
 
public class Main {
    static int avg(int[] arr) { //산술평균 메소드
        double result =0// 계산 후 반올림을 위해 double형
        double sum=0;
        for(int x : arr) { // 모두 더한다.
            sum+=x;
        }
        result = Math.round(sum / arr.length); // 반올림 후 저장
        
        return (int)Math.ceil(result); // int형으로 타입 캐스트
    }
    
    static int middle(int[] arr) { // 중앙값을 구하는 메소드
        
        return arr[(arr.length/2)]; // 그냥 2로 나눠주면 된다.
    }
    
    static int manny(int[] arr) { 
        int cnt[] = new int [8001];  // 입력값의 범위: -4000 ~ 4000
        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        int max = Integer.MIN_VALUE; // 최빈값을 찾기위한 비교변수
        for(int x:arr) {
            
            if(x<0) { // 음수의 경우 4000을 더해서 해당 인덱스를 증가
                cnt[Math.abs(x)+4000]++;
            }else cnt[x]++// 나머지는 인덱스만 증가
           
        }
        
    
        int idx =0;
        for(int i=0;i<cnt.length;i++) {
            if(cnt[i]!=0 && cnt[i]>max) {    //카운트 배열에서 최빈값을 찾는다.            
                max = cnt[i];
                idx = i;                
            }
        }
 
        for(int i=0;i<cnt.length;i++) {
            int x=i;
            if(cnt[i]==max) { // 카운트 배열의 값들과 최빈값과 일치하면,
                if(i>4000) { 
                    x-=4000;
                    x*=-1;
                    arrayList.add(x); // 어레이 리스트에 추가
                }else
                    arrayList.add(i); // 나머지는 그냥 i값을 추가
            }
        }
        Collections.sort(arrayList); // 추가 된 최빈값들이 다수 존재하면 오름차순 정렬
        
        if(arrayList.size()>1return arrayList.get(1); 
        else return     arrayList.get(0); // 그외에는 그냥 최빈값을 반환
    }
    
    static int range(int[] arr) { // 범위 메소드
        return arr[arr.length-1- arr[0]; // 정렬 후 마지막 숫자와 첫 번째 숫자를 빼준다.
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);        
        int n= sc.nextInt();
        int arr[] = new int[n];
        for(int i=0;i<n;i++) {
            arr[i] = sc.nextInt();
        }
        Arrays.sort(arr); // 입력받은 정수를 오름차순 정렬
        
        //각 메소드 호출 부
        System.out.println(avg(arr));
        System.out.println(middle(arr));
        System.out.println(manny(arr));
        System.out.println(range(arr));        
    }
}
cs

 

 

댓글