본문 바로가기
백준알고리즘

백준알고리즘:p2108 통계학

by socialcomputer 2021. 4. 5.
반응형

분류: 정렬

 

2021.03.20 - [백준알고리즘] - 백준알고리즘:p2108 통계학

전에 런타임 에러로 풀지 못했었는데 다시 풀어보았다. 

 

이전 코드 :

카운트 정렬을 통해 한번에 해결하려고 했다. 그런데 너무 복잡했고 런타임 에러도 있었다. 

또 평균에서 자꾸 문제가 있었는데 sum/n 할때 

sum을 double 실수형으로 바꿔주고 나눠야 했다. 그래야 소숫점에서 반올림을 하기 때문,,

그래서 -2가 나와야 하는데 자꾸 -1이 나와 대체 뭘까 했는데 이걸 생각지 못했다니ㅜㅜ 까먹지 말아야지;

 

새 코드 :

중간값, 최솟값과 최댓값의 차이는 int[]인 arr배열을 sort하여 해결했다. Arrays.sort(arr)

평균은 sum을 n으로 나눴다. 

최빈값은 카운트된 int[] cnt배열과, ArrayList를 이용해 해결했다. list

(flag를 이용해 해보기도 했다. )

 

최빈값 구하는 법을 더 말하자면, 최빈값이 여러개 일때는

두번째로 작은(=오름차순에서 두번째인) 수를 구하면 된다. 

그래서,

1. Arraylist를 이용해 카운트가 더 큰게 있으면 먼저 list를 clear해주고 add한다.

2. 다음 수의 카운트가 같은데 list 크기가 1이면 list에 add한다.

 

 

코드

//백준알고리즘 제출시 클래스 이름은 Main으로 바꿔야 됨 
package sort;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;

public class p2108_final {

	public static void main(String[] args) {
		try(	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
				BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));){
			int n = Integer.parseInt(br.readLine());
			int[] cnt = new int[8001]; //0 ~ 8000 -> -4000 ~ 4000
			int[] arr = new int[n];
			
			int sum=0;
			for(int i=0; i<n; i++) {
				int number = Integer.parseInt(br.readLine());
				arr[i]=number;
				cnt[number+4000] +=1;
				sum += number;
			}//숫자 다 받음
			
			Arrays.sort(arr);
			int mean = (int)Math.round((double)sum/n);//평균
			int center = arr[(n-1)/2];//중간값
			int coverage = arr[n-1]-arr[0];//최솟값과 최댓값 의 차(=범위)
			
			ArrayList<Integer> list = new ArrayList<>();
			int max = 0;
			boolean flag = false;
			for(int i=0; i<8001; i++) {
				if(cnt[i]>0) {
					if(cnt[i]>max) {
						max = cnt[i];
						list.clear();
						list.add(i-4000);
					}
					else if(list.size()==1 && cnt[i]==max) {
						list.add(i-4000);
					}
				}
			}
			
			bw.write(mean+"\n");
			bw.write(center+"\n");
			if(list.size()==1) {
				bw.write(list.get(0)+"\n");
			}else bw.write(list.get(1)+"\n");
			bw.write(coverage+"\n");
			bw.flush();			
			
		}catch (Exception e) {e.printStackTrace();}

	}

}

▶최빈값을 list없이 boolean flag로 구한 코드

package sort;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;

public class p2108_final {

	public static void main(String[] args) {
		try(	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
				BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));){
			int n = Integer.parseInt(br.readLine());
			int[] cnt = new int[8001]; //0 ~ 8000 -> -4000 ~ 4000
			int[] arr = new int[n];
			
			int sum=0;
			for(int i=0; i<n; i++) {
				int number = Integer.parseInt(br.readLine());
				arr[i]=number;
				cnt[number+4000] +=1;
				sum += number;
			}//숫자 다 받음
			
			Arrays.sort(arr);
			int mean = (int)Math.round((double)sum/n);//평균
			int center = arr[(n-1)/2];//중간값
			int coverage = arr[n-1]-arr[0];//최솟값과 최댓값 의 차(=범위)
			
			int max = 0; int max_bin=0;
			boolean flag = false;
			for(int i=0; i<8001; i++) {
				if(cnt[i]>0) {
					if(cnt[i]>max) {
						max = cnt[i];
						flag=true;
						max_bin = i-4000;
					}
					else if(flag==true && cnt[i]==max) {
						flag=false;
						max_bin = i-4000;
					}
				}
			}
			
			bw.write(mean+"\n");
			bw.write(center+"\n");
			bw.write(max_bin+"\n");
			bw.write(coverage+"\n");
			bw.flush();			
			
		}catch (Exception e) {e.printStackTrace();}

	}

}

 

 

 


채점결과

맨 위는 flag로 최빈값 구한 것, 맨 아래는 ArrayList로 최빈값 구한것

flag를 이용해 true false로 최빈값을 구하는 게 시간이 더 빠를 줄 알았는데 아니었다. 

ArrayList를 이용해 최빈값을 구하는게 더 빨랐다..

 

링크 www.acmicpc.net/problem/2108

 

2108번: 통계학

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

www.acmicpc.net

 

반응형

댓글