Open In App

Minimum K for which odd operations remove at least half of N

Last Updated : 23 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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++




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


Java




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


Python




# 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))


C#




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


Javascript




// 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


Output

3
1








Time Complexity: O(N*logN)
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads