Given integer N (1 <= N <= 1018). Perform the following operation until N is not zero, In odd operation remove K from N (if N is less than K remove all N). In an even operation remove 10% of N from the remaining N. The task for this problem is to find the minimum integer K for which the total N removed in odd operations is at least half of N.
Examples:
Input: N = 68
Output: 3
Explanation: Initially we have N = 68 if we choose K = 3
- In the first operation, we subtract K from N, and it becomes 65
- In the second operation we subtract 10% of N which is 6 (it should be 6.5 but we are only considering the integer part) after subtracting 6 from N, it becomes 59
- In the third operation, we subtract K from N, and it becomes 56
- In the fourth operation we subtract 10% of N which is 5(it should be 5.6 but we are only considering the integer part) after subtracting 5 from N, it becomes 51
- In the fifth operation, we subtract K from N, and it becomes 48
- In the sixth operation, we subtract 10% of N which is 4(it should be 4.8 but we are only considering the integer part) after subtracting 4 from N, it becomes 44
- In the seventh operation, we subtract K from N, and it becomes 41
- In the eighth operation we subtract 10% of N which is 4(it should be 4.1 but we are only considering the integer part) after subtracting 4 from N, it becomes 37
- In the ninth operation, we subtract K from N, and it becomes 34
- In the tenth operation we subtract 10% of N which is 3(it should be 3.4 but we are only considering the integer part) after subtracting 3 from N, it becomes 31
- In the 11th operation we subtract K from N, it becomes 28
- In 12th operation, we subtract 10% of N which is 2(it should be 2.8 but we are only considering integer part) after subtracting 2 from N, it becomes 26
- In the 13th operation we subtract K from N, it becomes 23
- In 14th operation we subtract 10% of N which is 2 (it should be 2.3 but we are only considering integer part) after subtracting 2 from N, it becomes 21
- In 15th operation we subtract K from N, it becomes 18
- In 16th operation we subtract 10% of N which is 1(it should be 1.8 but we are only considering integer part) after subtracting 1 from N, it becomes 17
- In 17th operation we subtract K from N, it becomes 14
- In 18th operation we subtract 10% of N which is 1(it should be 1.4 but we are only considering integer part) after subtracting 1 from N, it becomes 13
- In 19th operation we subtract K from N, it becomes 10
- In 20th operation we subtract 10% of N which is 1 after subtracting 1 from N, it becomes 9
- In 21st operation we subtract K from N, it becomes 6
- In 22nd operation we subtract 10% of N which is 0(it should be 0.6 but we are only considering integer part) after subtracting 0 from N, it remains 6
- In 23rd operation we subtract K from N, it becomes 3
- In 24th operation we subtract 10% of N which is 0(it should be 0.3 but we are only considering integer part) after subtracting 0 from N, it remains 3
- In 25th operation we subtract K from N, it becomes 0.
The total N removed in odd operations is 39 which is at least half of N
Input: N = 9
Output: 1
Efficient Approach: To solve the problem follow the below idea:
Binary Search can be used to solve this problem and the range of binary search will be 1 to N / 2 is monotonic function represents whether at least half of N removed in odd operations with K. it is of the form FFFFFFFTTTTTT. we have to find when the first time function is true using Binary Search.
Below are the steps for the above approach:
- Set low and high range of binary serach.
- isKpos(K, N) function used to check whether if K used for subtracting in odd operations removes at least half of N or not.
-
Run while loop till high and low are not adjacent.
- In while loop find middle element and store it in mid variable.
- Check if that mid can be used as K for subtracting in odd operations to remove at least half of N using isKpos() function. If it is true then set high = mid else low = mid + 1.
- After loop ends if isKpos() true for low then return low else return high.
Below is the implementation of the above approach:
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// Function to check for given K odd operations // remove at least half of N or not bool isKpos( int K, int N)
{ // Keeping count of odd operations
int oddTotalRemoved = 0;
// Current N
int curN = N;
// Run till current N is not zero
while (curN > 0) {
// For odd operations remove K and add
// it in total removed in odd operations
oddTotalRemoved += min(K, curN);
// Removing K from current N
curN -= min(curN, K);
// Removing 10% of current N
curN = curN - curN / 10;
}
// If total N removed in odd operations are
// greater than half of N than return true
// else return false
return oddTotalRemoved * 2 >= N;
} // Function to find Minimum K for // which odd operations remove at // least half of N int findMinimumK( int N)
{ // Range of binary search
int low = 1, high = (N / 2) + 1;
// Running loop till high
// is not equal to low
while (high - low > 1) {
// mid is average of low and high
int mid = (low + high) / 2;
// Checking test function
if (isKpos(mid, N)) {
high = mid;
}
else {
low = mid + 1;
}
}
// Checking whether low can be answer
if (isKpos(low, N))
return low;
// If not then it is high
else
return high;
} // Driver Code int32_t main() { // Input 1
int N = 68;
// Function Call
cout << findMinimumK(N) << endl;
// Input 2
int N1 = 9;
// Function Call
cout << findMinimumK(N1) << endl;
return 0;
} |
import java.util.*;
public class MinimumK {
// Function to check for given K odd operations
// remove at least half of N or not
static boolean isKpos( int K, int N) {
// Keeping count of odd operations
int oddTotalRemoved = 0 ;
// Current N
int curN = N;
// Run until current N is not zero
while (curN > 0 ) {
// For odd operations, remove K and add
// it to total removed in odd operations
oddTotalRemoved += Math.min(K, curN);
// Removing K from current N
curN -= Math.min(curN, K);
// Removing 10% of current N
curN = curN - curN / 10 ;
}
// If the total N removed in odd operations is
// greater than or equal to half of N, return true,
// else return false
return oddTotalRemoved * 2 >= N;
}
// Function to find Minimum K for
// which odd operations remove at
// least half of N
static int findMinimumK( int N) {
// Range of binary search
int low = 1 , high = (N / 2 ) + 1 ;
// Running loop until high is not equal to low
while (high - low > 1 ) {
// mid is the average of low and high
int mid = (low + high) / 2 ;
// Checking test function
if (isKpos(mid, N)) {
high = mid;
} else {
low = mid + 1 ;
}
}
// Checking whether low can be the answer
if (isKpos(low, N))
return low;
// If not, then it is high
else
return high;
}
// Driver Code
public static void main(String[] args) {
// Input 1
int N = 68 ;
// Function Call
System.out.println(findMinimumK(N));
// Input 2
int N1 = 9 ;
// Function Call
System.out.println(findMinimumK(N1));
}
} |
# Function to check for given K odd operations # remove at least half of N or not def isKpos(K, N):
# Keeping count of odd operations
oddTotalRemoved = 0
# Current N
curN = N
# Run till current N is not zero
while curN > 0 :
# For odd operations remove K and add
# it in total removed in odd operations
oddTotalRemoved + = min (K, curN)
# Removing K from current N
curN - = min (curN, K)
# Removing 10% of current N
curN = curN - curN / / 10
# If total N removed in odd operations are
# greater than half of N than return true
# else return false
return oddTotalRemoved * 2 > = N
# Function to find Minimum K for # which odd operations remove at # least half of N def findMinimumK(N):
# Range of binary search
low, high = 1 , (N / / 2 ) + 1
# Running loop till high
# is not equal to low
while high - low > 1 :
# mid is average of low and high
mid = (low + high) / / 2
# Checking test function
if isKpos(mid, N):
high = mid
else :
low = mid + 1
# Checking whether low can be the answer
if isKpos(low, N):
return low
# If not then it is high
else :
return high
# Driver Code # Input 1 N = 68
# Function Call print (findMinimumK(N))
# Input 2 N1 = 9
# Function Call print (findMinimumK(N1))
|
using System;
class GFG
{ // Function to check for given K odd operations
// remove at least half of N or not
static bool isKpos( int K, int N)
{
// Keeping count of odd operations
int oddTotalRemoved = 0;
// Current N
int curN = N;
// Run until current N is not zero
while (curN > 0)
{
// For odd operations remove K and add
// it in total removed in odd operations
oddTotalRemoved += Math.Min(K, curN);
// Removing K from current N
curN -= Math.Min(curN, K);
// Removing 10% of current N
curN = curN - curN / 10;
}
// If total N removed in odd operations is
// greater than or equal to half of N, return true
// else return false
return oddTotalRemoved * 2 >= N;
}
// Function to find Minimum K for
// which odd operations remove at
// least half of N
static int findMinimumK( int N)
{
// Range of binary search
int low = 1, high = (N / 2) + 1;
// Running loop until high
// is not equal to low
while (high - low > 1)
{
// mid is the average of low and high
int mid = (low + high) / 2;
// Checking test function
if (isKpos(mid, N))
{
high = mid;
}
else
{
low = mid + 1;
}
}
// Checking whether low can be the answer
if (isKpos(low, N))
return low;
// If not, then it is high
else
return high;
}
// Driver Code
public static void Main()
{
// Input 1
int N = 68;
// Function Call
Console.WriteLine(findMinimumK(N));
// Input 2
int N1 = 9;
// Function Call
Console.WriteLine(findMinimumK(N1));
}
} |
// Function to check for given K odd operations // remove at least half of N or not function isKpos(K, N) {
// Keeping count of odd operations
let oddTotalRemoved = 0;
// Current N
let curN = N;
// Run until current N is not zero
while (curN > 0) {
// For odd operations remove K and add
// it in total removed in odd operations
oddTotalRemoved += Math.min(K, curN);
// Removing K from current N
curN -= Math.min(curN, K);
// Removing 10% of current N
curN = curN - Math.floor(curN / 10);
}
// If total N removed in odd operations is
// greater than half of N, then return true
// else return false
return oddTotalRemoved * 2 >= N;
} // Function to find Minimum K for // which odd operations remove at // least half of N function findMinimumK(N) {
// Range of binary search
let low = 1, high = Math.floor(N / 2) + 1;
// Running loop until high
// is not equal to low
while (high - low > 1) {
// mid is the average of low and high
let mid = Math.floor((low + high) / 2);
// Checking test function
if (isKpos(mid, N)) {
high = mid;
} else {
low = mid + 1;
}
}
// Checking whether low can be the answer
if (isKpos(low, N)) {
return low;
} else {
// If not, then it is high
return high;
}
} // Driver Code let N = 68; // Function Call console.log(findMinimumK(N)); // Input 2 let N1 = 9; // Function Call console.log(findMinimumK(N1)); // This code is contributed by rambabuguphka |
3 1
Time Complexity: O(N*logN)
Auxiliary Space: O(1)