Monday, 10 August 2015

MINIMUM NO REQUIRED TO FORM SUM=N

Q- u have given first k numbers ie 1,2,3,4,5,6,7,8......k , find minimum no of numbers (sum of those number )required to form a number n using these 1,2,3,...k num bers ,
any number  can be use only 1 time


*******************************editorial**********************************
 we can do this using binary search (discreet binary search ) ..
  case 1 -if that number is> k*(k+1)/2.than it cant be formed using these numbers
 case 2-
    we can solve this problem using binary search ,,  since we want to use minimum numbers of number so first we use bigger numbers (k,k-1,k-2....) and  after that we will observe either 1 smaller number of may be not a single smaller number required to form that number ..
 ex- form 14 using 1 ,2,3,4,5,6,7
 we use 7,6,1-- only 1 smaller number 
 form 9 we use 7,2.
 form 10 -  we will use 7 ,3
 form 20we will use 7,6,5, 2 -- only 1 smaller number ..
form 18 use 7,6,5 not required any smaller number ..


soo using duiscreat binary search we first find   maximum numbers from right (k,k-1,...) we can pick
and after that we will either use  one smaller number (if required ) or do not use any smaller number ..



*********************************code**************************************


#include<iostream>
using namespace std;
typedef long long int lli;
 lli func(lli n,lli k)
  {
  lli lo=1;
   lli hi=k;
    lli ans=-1;
     lli cnt=k;
 
    int te=10;
    while(lo<=hi)
     {
     
      lli mid=(lo+hi)/2;
     
      lli cover=(k-mid);
     
       lli val=(k*(k+1)/2)-((mid)*(mid+1))/2;
     
       if(val<=n   && val>ans )
        {
       
         ans=val;
         cnt=k-mid;
         if(val==n)break;
         else hi=mid;
       
       
       
}
else
 {
  lo=mid+1;
 }
     
 }

   return cnt;
  }

 int main()
  {
 
  int t;
  cin>>t;
   while(t--)
    {
    lli n,k;
    cin>>n>>k;
     if(n>(k*(k+1))/2)
      {
      cout<<"cant form this number it higher in range "<<endl;
                        }
      else
       {
        lli ans=func(n,k);// ans is number of number used from right (ie k,k-1,..)
       
         lli nw=k-ans;
                       
         lli sum=(k*(k+1)/2)-((nw*(nw+1))/2);// sum  formed from selected numbers
        if(ans==k)// means all numbers used
         {
          cout<<"-1"<<endl;
         
}
else if(n!=sum)// means one small number required from left
cout<<ans+1<<endl;
else cout<<ans<<endl;
       
 }
}
}
 

No comments:

Post a Comment