Thursday 11 September 2014

Cut the sticks problem



You are given N sticks, where each stick is of positive integral length. A cut operation is performed on the sticks such that all of them are reduced by the length of the smallest stick.
Suppose we have 6 sticks of length
5 4 4 2 2 8
then in one cut operation we make a cut of length 2 from each of the 6 sticks. For next cut operation 4 sticks are left (of non-zero length), whose length are
3 2 2 6
Above step is repeated till no sticks are left.
Given length of N sticks, print the number of sticks that are cut in subsequent cut operations.
Input Format  The first line contains a single integer N.  The next line contains N integers: a0, a1,...aN-1 separated by space, where ai represents the length of ith stick.
Output Format  For each operation, print the number of sticks that are cut in separate line.
Constraints  1 ≤ N ≤ 1000  1 ≤ ai ≤ 1000
Sample Input #00
6
5 4 4 2 2 8
Sample Output #00
6
4
2
1
Sample Input #01
8
1 2 3 4 3 3 2 1
Sample Output #01
8
6
4
1
Explanation
Sample Case #00 :
sticks-length        length-of-cut   sticks-cut
5 4 4 2 2 8             2               6
3 2 2 _ _ 6             2               4
1 _ _ _ _ 4             1               2
_ _ _ _ _ 3             3               1
_ _ _ _ _ _           DONE            DONE
Sample Case #01
sticks-length         length-of-cut   sticks-cut
1 2 3 4 3 3 2 1         1               8
_ 1 2 3 2 2 1 _         1               6
_ _ 1 2 1 1 _ _         1               4
_ _ _ 1 _ _ _ _         1               1
_ _ _ _ _ _ _ _       DONE            DONE

Programming in C : 

#include < stdio.h>
#include < string.h>
#include < math.h>
#include < stdlib.h>

int main() {

    int N,*a,i,j,k,min,count=0;
    scanf("%d",&N);
    a=(int*)malloc(sizeof(int)*N);
    for(i=0;i<N;i++)
    scanf("%d",&a[i]);
    while(1){
    min=1000;
    for(i=0;i<N;i++)
    {     
    if(a[i]==0)
    {
     continue;   
    }
    else{
     if(min>a[i])
      min=a[i];      
    }       
    }
    count=0;
    for(i=0;i<N;i++){
    if(a[i]==0)
    continue;
    else{    
    a[i]=a[i]-min;
    count++;    
    }    
    }
    if(count==0) break;    
    printf("%d\n",count);
    if(count==1) break;    
    }
        return 0;
}



1 comment:

  1. This problem can also be solved by Range Minimum Queries and Range Updates using segment tree built over the array and propagating the updates lazily.

    We just need to ensure that the result is never negative.

    Total Complexity therefore is:

    precomputation : O(n)
    update : O(log n)
    finding minimum : O(log n)

    total : O(n + q*log n)

    where q is numbee of steps performed.

    ReplyDelete