ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 11582(치킨 TOP N) C언어
    백준 문제 2021. 9. 10. 01:32
    728x90

    문제

     

    11582번: 치킨 TOP N

    인하대 주변 치킨칩의 맛의 정도를 측정해 수치화하는 동아리 C.T.P(Chicken Tastes Perfect)의 회장 민호는 치킨집의 맛의 수치를 감소하지 않는 순으로 정렬을 하고 싶었다. 하지만 치킨집이 너무 많

    www.acmicpc.net

    간단한 머지소트 응용문제입니다. 그러다가 중간에 조건이 주어지고 그 조건에 들어가면 머지 소트를 멈추고

    그대로 출력하는 문제입니다.

    코드를 보겠습니다.

    int arr[1048577];
    int tmp[1048577];
    int n;
    int k;
    int main(){
       scanf("%d",&n);
       for(int i=0;i<n;i++){
          scanf("%d",arr[i]);
       }
       
       scanf("%d",&k);
       merge_sort(arr,0,n-1);
       
       for (int i = 0; i < n; i++) {
    		printf("%d ",arr[i]);
    	}
        return 0;
    }

    정렬해야할 수가 2^20까지 이므로 배열의 크기를 2^20+1 까지 잡습니다.

    배열과 변수 n, 변수 k를 전역변수로 설정한 이유는 머지소트를 함수로 구현하기 위함입니다.

    main함수에서는 n을 입력받고, 정렬해야할 arr배열의 값을 입력받고 병합해야할 사람의 숫자인 k를 입력받습니다.

    그다음 merge_sort 함수를 실행하고 마지막으로 정렬된 arr배열의 값을 출력시킵니다.


    merge_sort부분입니다.

    void merge_sort(int arr[], int l, int r) {
    	if (l < r) {
    		int m = (l + r) / 2;
    		merge_sort(arr, l, m);
    		merge_sort(arr, m + 1, r);
    		merge(arr, l, m, r);
    	}
    }

    일반 머지소트 방식과 유사합니다. 넘어가겠습니다.


    merge부분입니다.

    void merge(int arr[], int l, int m, int r) {
    	if (r-l>n/k)
    		return;
    	int idx1, idx2, idx3;
    	idx1= idx3 = l;
    	idx2 = m + 1;
    	while (idx1 <= m && idx2 <= r) {
    		if (arr[idx1] < arr[idx2])
    			tmp[idx3++] = arr[idx1++];
    		else {
    			tmp[idx3++] = arr[idx2++];
    		}
    	}
    	if (idx1 == m + 1) {
    		for (int i = idx2; i <= r; i++) {
    			tmp[idx3++] = arr[i];
    		}
    	}
    	else {
    		for (int i = idx1; i <= m; i++) {
    			tmp[idx3++] = arr[i];
    		}
    	}
    	for (int i = l; i <= r; i++) {
    		arr[i] = tmp[i];
    	}
    }

    merge부분도 일반 merge부분과 매우 유사합니다. 하지만 if(r - l >n/k) return;  여기서 제일 중요한 코드입니다.

    n / k부분은 1사람당 병합해야할 배열의 크기를 의미합니다. 또한 merge 함수 내에서 r - l 은 병합해야할 배열의

    크기입니다.

    예를 들어 n이 8이고 k가 2면 1사람당 병합해야할 배열의 크기가 4이고 만약 병합해야할 배열의 크기가 4보다 크면

    2의 거듭제곱으로 배열의 크기가 8인 배열을 병합해야하므로 이는 k가 1일 때 가능합니다.

    나머지는 일반 merge함수와 똑같습니다.


    전체 코드입니다.

    #include<stdio.h>
    void merge_sort(int arr[], int l, int r);
    void merge(int arr[], int l, int m, int r);
    int n;
    int k;
    int arr[1048577];
    int tmp[1048577];
    int main() {
    	scanf("%d",&n);
    	for (int i = 0; i < n; i++) {
    		scanf("%d",&arr[i]);
    	}
    	scanf("%d",&k);
    	merge_sort(arr, 0, n - 1);
    	for (int i = 0; i < n; i++) {
    		printf("%d ",arr[i]);
    	}
    	return 0;
    }
    void merge_sort(int arr[], int l, int r) {
    	if (l < r) {
    		int m = (l + r) / 2;
    		merge_sort(arr, l, m);
    		merge_sort(arr, m + 1, r);
    		merge(arr, l, m, r);
    	}
    }
    void merge(int arr[], int l, int m, int r) {
    	if (r-l>n/k)
    		return;
    	int idx1, idx2, idx3;
    	idx1= idx3 = l;
    	idx2 = m + 1;
    	while (idx1 <= m && idx2 <= r) {
    		if (arr[idx1] < arr[idx2])
    			tmp[idx3++] = arr[idx1++];
    		else {
    			tmp[idx3++] = arr[idx2++];
    		}
    	}
    	if (idx1 == m + 1) {
    		for (int i = idx2; i <= r; i++) {
    			tmp[idx3++] = arr[i];
    		}
    	}
    	else {
    		for (int i = idx1; i <= m; i++) {
    			tmp[idx3++] = arr[i];
    		}
    	}
    	for (int i = l; i <= r; i++) {
    		arr[i] = tmp[i];
    	}
    }

    '백준 문제' 카테고리의 다른 글

    백준 1448(삼각형 만들기) c++  (0) 2021.09.11
    백준 1377(버블 소트) c++  (0) 2021.09.11
    백준 10610(30) c++  (0) 2021.09.09
    백준 2346(풍선 터뜨리기) c++  (0) 2021.09.06
    백준 9093번(단어 뒤집기) c++  (0) 2021.09.06
Designed by Tistory.