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;
}
}
}
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