2016年8月28日 星期日

HackerRank Cut the sticks(Algorithms>Implementation)

題目:
給定N根樹枝,每根的長度均為正整數,
每次進行cut的操作直到所有的樹枝都被削減到最小的長度。
假設我們有6根樹枝,長度如下:
5 4 4 2 2 8
在一次cut的操作中,我們將6根樹枝都減去2的長度,
在下一次cut的操作之前就只有4根樹枝留下(非0長度的樹枝),
其長度為:
3 2 2 6
重複上述的操作直到沒有樹枝留下。

輸入:
第一行包含1個integer N。
下一行為N個integers:a_0, a_1, ... a_N-1,以空格空開,
代表各樹枝的長度。

輸出:
在每次的操作中,印出當次有幾根樹枝被cut。

解題:
第一次肯定是全部的樹枝都會被cut,
而被cut成0的樹枝,就是當下長度最小的那幾根。
故,只要我們將樹枝由小到大排列,
就可以知道每次會被cut成0的樹枝數,
也就知道每次有幾隻樹枝會被cut。
我們直接使用ANSI C中的qsort進行排序。

qsort要分別提供陣列pointer,陣列長度,
陣列元素的大小,以及比較大小用的function。

底下這邊使用cut_num來計算每次cut有幾隻樹枝被cut掉,
再逐次以remain_num扣掉並印出來。

Code:
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>

int compare(const void *arg1, const void *arg2){
     return  (*(int *)arg1 - *(int *)arg2);
}

int main(){
    int n; 
    scanf("%d",&n);
    int arr[n];
    for(int arr_i = 0; arr_i < n; arr_i++){
       scanf("%d",&arr[arr_i]);
    }
    qsort((void *)arr, n, sizeof(int), compare);
    int remain_num = n, cut_num = 1;
    printf("%d\n", remain_num);
    
    for(int i = 1; i < n ; i++){
        if (arr[i] > arr[i-1]){
            remain_num -= cut_num;
            printf("%d\n", remain_num);
            cut_num = 1;
        }else {
            cut_num++;
        }
    }
    return 0;
}

沒有留言:

張貼留言