알고리즘/2023 구름톤 챌린지

구름톤 챌린지 1주차 - 2

hw-ani 2023. 8. 18. 22:14

2023.08.17.(목)

#include <stdio.h>
int main() {
    int N;
    scanf("%d", &N);
    
    int k[1002], max = 0, max_position = -1, sum = 0;
    for (int i=0; i<N; i++) {
        scanf("%d", &k[i]);
        sum += k[i];
        if (k[i] > max) {
            max = k[i];
            max_position = i;
        }
    }
    
    int notPerfect = 0;
    if (max_position == 0) {
        for (int i = max_position + 1; i<N; i++) {
            if (k[i] > k[i-1]) {
                notPerfect = 1;
                break;
            }
        }
    }
    else if (max_position == N-1) {
        for (int i = max_position - 1; i > -1; i--) {
            if (k[i] > k[i+1]) {
                notPerfect = 1;
                break;
            }
        }
    }
    else {
        for (int i = max_position + 1; i<N; i++) {
            if (k[i] > k[i-1]) {
                notPerfect = 1;
                break;
            }
        }
        for (int i = max_position - 1; i > -1; i--) {
            if (k[i] > k[i+1]) {
                notPerfect = 1;
                break;
            }
        }
    }
    
    if (notPerfect)
        printf("0");
    else
        printf("%d", sum);
}

최댓값이 있는 위치를 찾은 후 좌, 우로 훑으며 내림차순으로 잘 내려가는지 반복문으로 확인했습니다.

최댓값이 양쪽 끝에 있는 경우를 따로 처리해줬고, 내림차순으로 잘 내려가지 않는다면 notPerfect를 1로 설정해 0을 출력하도록 하였습니다.

 

 

 


2023.08.18.(금)

#include <stdio.h>

#define SIZE 500002

typedef struct element{
    int value;
    int numberOfBits;
} element;

// prototype of functions

int getNumberOfBits(int value);
void mergeSort(element numbers[], int r, int l, int (*comp)(element *a, element *b));
void merge(element numbers[], int r, int m, int l, int (*comp)(element *a, element *b));
int comp1(element *a, element *b);
int comp2(element *a, element *b);


int main() {
    int N, K;
    scanf("%d %d", &N, &K);
    element numbers[SIZE];
    for (int i=0; i<N; i++) {
        scanf("%d", &(numbers[i].value));
        numbers[i].numberOfBits = getNumberOfBits(numbers[i].value);
    }
    
    // 문제 조건에 따라 일단 숫자를 기준으로 내림차순 정렬하고
    // 그 다음 비트 중 1의 수을 기준으로 정렬하도록 하였다.
    // 그러면 비트 수 내림차순으로 정렬되고, 같은 비트 개수를 가지면 숫자 내림차순으로 정렬된다!
    // merge sort는 stable sort이니 가능한 것
    mergeSort(numbers, 0, N-1, comp1);
    mergeSort(numbers, 0, N-1, comp2);
    
    printf("%d", numbers[K-1].value);
    
    return 0;
}

// Divide
void mergeSort(element numbers[], int r, int l, int (*comp)(element *a, element *b)) {  // r~l
    if (r<l) {
        int m = (r+l)/2;
        mergeSort(numbers, r, m, comp);
        mergeSort(numbers, m+1, l, comp);
        merge(numbers, r, m, l, comp);
    }
}

// Merge
void merge(element numbers[], int r, int m, int l, int (*comp)(element *a, element *b)) {  // [r,m], [m+1,l]
    element temp[SIZE];
    int i=r, j=m+1, k=0;
    for (; i<=m && j<=l;) {
        if (comp(&numbers[i], &numbers[j]))
            temp[k++] = numbers[i++];
        else
            temp[k++] = numbers[j++];
    }
    for (;i<=m;)
        temp[k++] = numbers[i++];
    for (;j<=l;)
        temp[k++] = numbers[j++];
    
    for (int x=r; x<=l; x++) {
        numbers[x] = temp[x-r];
    }
}

int getNumberOfBits(int value) {
    int result = 0;
    for (;value != 0; value/=2)
        if (value % 2 == 1)
                result++;
    return result;
}

int comp1(element *a, element *b) {
    return a->value >= b->value;  // '>'가 아니라 '>='로 비교해야 함!
}

int comp2(element *a, element *b) {
    return a->numberOfBits >= b->numberOfBits;  // '>'가 아니라 '>='로 비교해야 함!
}

비트 수를 세는 별도의 함수인 getNumberOfBits()를 구현하였고, 반복문에서 2로 나누며 비트 중 1의 개수를 세서 반환하도록 하였습니다.

비트 중 1의 개수를 기준으로 정렬해야하는데, 같은 개수를 가진다면 숫자 값 자체를 기준으로 정렬해야합니다. 그래서 stable sort를 이용해 일단 숫자 자체를 기준으로 내림 차순으로 정렬하도록 한 뒤, 비트 중 1의 수를 기준으로 정렬하도록 하였습니다.

즉, 두번 정렬하는데, 처음 정렬한 순서를 유지해야하므로 stable sort 중 하나인 merge sort를 구현하여 사용했습니다.

여기서 짚어볼만한 점은, 위 구현 방식의 merge sort가 stable sort가 되도록 하기 위해선 비교를 할 때 크다(>)가 아니라 크거나같다(>=)를 활용해야 한다는 것입니다. 그래야 두 값을 비교해서 같은 값일 때 왼쪽의 값이 먼저 들어가서 stable sort가 됩니다.

(mergeSort() 함수에서 comp 함수의 반환값을 1(크다),0(같다),-1(작다) 중 하나로 반환하게 해서 강제하는 식으로 구현했으면 일반화가 잘 됐을 것 같음. 지금 이 함수는 comp 함수 만들 때 실수로 그냥 '<' 이런거 써서 비교하면 stable sort가 안되니까 좀 더 강제하는 방식으로 구현하면 좋을 듯)

 

'알고리즘 > 2023 구름톤 챌린지' 카테고리의 다른 글

구름톤 챌린지 2주차 - 2  (2) 2023.08.27
구름톤 챌린지 2주차 - 1  (0) 2023.08.24
구름톤 챌린지 1주차 - 1  (0) 2023.08.16