[백준] 24060

당당·2023년 5월 18일
0

백준

목록 보기
113/179

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

📔문제

오늘도 서준이는 병합 정렬 수업 조교를 하고 있다. 아빠가 수업한 내용을 학생들이 잘 이해했는지 문제를 통해서 확인해보자.

N개의 서로 다른 양의 정수가 저장된 배열 A가 있다. 병합 정렬로 배열 A를 오름차순 정렬할 경우 배열 AK 번째 저장되는 수를 구해서 우리 서준이를 도와주자.

크기가 N인 배열에 대한 병합 정렬 의사 코드는 다음과 같다.

merge_sort(A[p..r]) { # A[p..r]을 오름차순 정렬한다.
    if (p < r) then {
        q <-(p + r) / 2;       # q는 p, r의 중간 지점
        merge_sort(A, p, q);      # 전반부 정렬
        merge_sort(A, q + 1, r);  # 후반부 정렬
        merge(A, p, q, r);        # 병합
    }
}

# A[p..q]A[q+1..r]을 병합하여 A[p..r]을 오름차순 정렬된 상태로 만든다.
# A[p..q]A[q+1..r]은 이미 오름차순으로 정렬되어 있다.
merge(A[], p, q, r) {
    i <- p; j <- q + 1; t <- 1;
    while (i ≤ q and j ≤ r) {
        if (A[i]A[j])
        then tmp[t++] <- A[i++]; # tmp[t] <- A[i]; t++; i++;
        else tmp[t++] <- A[j++]; # tmp[t] <- A[j]; t++; j++;
    }
    while (i ≤ q)  # 왼쪽 배열 부분이 남은 경우
        tmp[t++] <- A[i++];
    while (j ≤ r)  # 오른쪽 배열 부분이 남은 경우
        tmp[t++] <- A[j++];
    i <- p; t <- 1;
    while (i ≤ r)  # 결과를 A[p..r]에 저장
        A[i++] <- tmp[t++]; 
}

📝입력

첫째 줄에 배열 A의 크기 N(5 ≤ N ≤ 500,000), 저장 횟수 K(1 ≤ K ≤ 10^8)가 주어진다.

다음 줄에 서로 다른 배열 A의 원소 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 10^9)


📺출력

배열 AK 번째 저장 되는 수를 출력한다. 저장 횟수가 K 보다 작으면 -1을 출력한다.


📝예제 입력 1

5 7
4 5 1 3 2

📺예제 출력 1

3

4 5 1 3 2 -> 4 5 1 3 2 -> 4 5 1 3 2 -> 1 5 1 3 2 -> 1 4 1 3 2 -> 1 4 5 3 2 -> 1 4 5 2 2 -> 1 4 5 2 3 -> 1 4 5 2 3 -> 1 2 5 2 3 -> 1 2 3 2 3 -> 1 2 3 4 3 -> 1 2 3 4 5. 총 12회 저장이 발생하고 일곱 번째 저장되는 수는 3이다.


📝예제 입력 2

5 13
4 5 1 3 2

📺예제 출력 2

-1

저장 횟수 12가 K 보다 작으므로 -1을 출력한다.


🔍출처

-문제를 검수한 사람: chansol, eric00513, jhnah917, jthis, kdh6429, parkky, tony9402
-문제를 만든 사람: MenOfPassion


🧮알고리즘 분류

  • 구현
  • 정렬
  • 재귀

📃소스 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Code24060 {
    static int count=0;
    static int K=0;
    static int answer=-1;
    static int[] arr,tmp;
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer(br.readLine());

        int size=Integer.valueOf(st.nextToken());
        K=Integer.valueOf(st.nextToken());

        st=new StringTokenizer(br.readLine());

        arr=new int[size];
        tmp=new int[size];
        br.close();
        for(int i=0;i<size;i++){
            arr[i]=Integer.valueOf(st.nextToken());
        }

        merge_sort(arr,0,size-1);
        System.out.println(answer);

    }

    public static void merge_sort(int[] A,int p,int r){
        int q;
        if(p<r){
            q=(p+r)/2;
            merge_sort(A,p,q);
            merge_sort(A,q+1,r);
            merge(A,p,q,r);
        }
    }
    public static void merge(int[] A,int p,int q, int r){
        int i=p;
        int j=q+1;
        int t=0;
        int len=A.length;
        while(i<=q && j<=r){
            if(A[i]<=A[j]){
                tmp[t++]=A[i++];
            }
            else{
                tmp[t++]=A[j++];
            }
        }

        while(i<=q){
            tmp[t++]=A[i++];
        }
        while(j<=r){
            tmp[t++]=A[j++];

        }
        i=p;
        t=0;
        while(i<=r){
            A[i++]=tmp[t++];
            count++;
            if(count==K){
                answer=tmp[t-1];
                break;
            }
        }
    }
}


📰출력 결과


📂고찰

어쩌란건지 몰랐다. 왜냐하면 알고리즘 로직은 문제에 나와있는 대로 구현했으니까..

문제점을 찾았다..StringTokenizersplit()대신 쓸 것

이거 하나로 시간초과가 안났다..

그다음 배열 선언을 전역변수로 해야했다..

profile
MySQL DBA 신입 지원

0개의 댓글