Sherlock and Counting

Sort by

recency

|

34 Discussions

|

  • + 0 comments

    What's wrong with this?

    def solve(n, k): if n <= 4*k: return n-1 else: a = math.sqrt(n) b = math.sqrt(n-4*k) c = a*(a-b)/2 return 2*int(c)

  • + 0 comments

    Problem Explanation:

    You're given several test cases, each consisting of two integers n and k. For each test case, you need to determine the number of values x that satisfy certain conditions.

    Based on the provided code, it seems the problem involves splitting the number n into two parts (r and n - r) and checking if their product is less than or equal to n * k. The goal is to find the largest valid split and output twice the largest valid r.

    Key Concepts:

    • Objective: For each test case, you are given n and k. You need to:

      1. Find how many values of r can split n into two parts such that the product of the two parts is less than or equal to n * k.
      2. Output twice the largest valid r that satisfies this condition.
    • Mathematical Formulation: The problem checks the condition r * (n - r) <= n * k, where r is an integer between 1 and n/2.

    Steps in the Solution:

    1. Input:

      • You receive multiple test cases where each test case contains two integers n and k.
      • The number n represents an upper limit, and k is a factor that impacts how large the product of the split can be.
    2. Initial Check:

      • First, check whether the product of n/2 * (n - n/2) is less than or equal to n * k.
        • This is because splitting n evenly into two parts (n/2 and n - n/2) generally maximizes the product of the two parts.
      • If this condition is satisfied, or if n == 1 (since splitting doesn't make sense for n = 1), print n - 1 and stop further calculation.
        • For n == 1, there's only one valid number x (which is 0), so the result is n - 1 = 0.
    3. Binary Search:

      • If the initial condition fails, use binary search to find the largest r such that r * (n - r) <= n * k.
      • Binary search works because:
        • The function r * (n - r) behaves in a predictable way as r increases: it starts small, peaks at n/2, and then decreases.
      • The idea is to efficiently find the largest value of r that satisfies the condition.
      • The search is conducted within the range [1, n/2] because the split becomes redundant after n/2 (e.g., r > n/2 would be the same as having r <= n/2 due to symmetry).
    4. Binary Search Logic:

      • You calculate the midpoint mid of the current search range [l, r].
      • If mid * (n - mid) <= n * k, it means this split is valid, and you try to move the left pointer l to explore larger values of r.
      • If the condition is not satisfied, move the right pointer r to explore smaller values of r.
      • The goal is to find the largest r for which the condition holds.
    5. Final Result:

      • Once the binary search is complete, the largest valid r is found, and the result is 2 * r (as required by the problem).

    Example Walkthrough:

    Test Case 1:

    • Input: n = 5, k = 1

      • First, check if n/2 * (n - n/2) <= n * k.
      • 5 / 2 * (5 - 5 / 2) = 2 * 3 = 6
      • 5 * 1 = 5
      • Since 6 > 5, we move to the binary search.

      • Perform binary search over the range [1, 5/2 = 2]:

      • Try mid = 1: 1 * (5 - 1) = 1 * 4 = 4, which is less than or equal to 5 * 1 = 5. So, move l = 2.
      • Try mid = 2: 2 * (5 - 2) = 2 * 3 = 6, which is greater than 5. So, move r = 1.

      • The largest valid r is 1, and the result is 2 * r = 2.

    Test Case 2:

    • Input: n = 5, k = 2

      • First, check if n/2 * (n - n/2) <= n * k.
      • 5 / 2 * (5 - 5 / 2) = 2 * 3 = 6
      • 5 * 2 = 10
      • Since 6 <= 10, print n - 1 = 4.

    Summary of Solution Steps:

    1. For each test case:
      • Compute whether the product of two halves of n (n/2 * (n - n/2)) is less than or equal to n * k.
      • If yes, print n - 1.
      • If no, use binary search to find the largest value of r such that r * (n - r) <= n * k.
      • Print 2 * r as the result.

    This process ensures that you efficiently find the correct number of valid splits for each test case based on the given condition.

  • + 1 comment

    Python 3: ans: 1~left root + right root ~n-1

    def solve(n, k):
        if 4*k>=n: return n-1
        x1=(n-math.sqrt(n**2-4*n*k))/2
        x2=(n+math.sqrt(n**2-4*n*k))/2
        return math.floor(x1)+n-math.ceil(x2)
    
  • + 0 comments

    If you use the quadratic formula be careful with (b^2 - 4.a.c == 0). Cheers everyone.

  • + 0 comments

    Btw, it's also possible to pass test cases in this perticular problem using Binary Search. just find the max possible i between 1 and n/2, where, i.(n-i) <= n.k and the answer is two times that. also need to take care of the edge case of n/2 . (n - n/2) <= n . k.

    #include <iostream>
    
    #define forn(i,e) for(ll i = 0; i < e; i++)
    #define forsn(i,s,e) for(ll i = s; i < e; i++)
    #define rforn(i,s) for(ll i = s; ~i; i--)
    #define pb push_back
    #define ff first
    #define ss second
    
    using namespace std;
    typedef long long ll;
    const ll MOD=1000000007;
    
    void solve(){
        ll n, k;
        cin >> n >> k;
    
        if(n/2 * (n-n/2) <= n*k || n==1) {
            cout << n-1 << '\n';
            return;
        }
    
        ll l=1, r=n/2;
        while(l <= r){
            ll mid = l + (r-l)/2;
    
            if(mid*(n-mid) <= n*k) l=mid+1;
            else r=mid-1;
        }
    
        cout << 2*r << '\n';
    }
    
    int main(){
    #ifdef k4droid3
        freopen("input.txt", "r", stdin);
    #endif
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
    
        int t;
        cin >> t;
        while(t--)
            solve();
        
        return 0;
    }