CF 104782C - Basketball

We are asked to construct a target score using only two types of basketball throws: one type adds 2 points and the other adds 3 points. Given an integer n, we need to determine whether it is possible to form exactly n points using some combination of these throws.

CF 104782C - Basketball

Rating: -
Tags: -
Solve time: 41s
Verified: yes

Solution

Problem Understanding

We are asked to construct a target score using only two types of basketball throws: one type adds 2 points and the other adds 3 points. Given an integer n, we need to determine whether it is possible to form exactly n points using some combination of these throws. If it is possible, we must also minimize the total number of throws used. Among all valid combinations, we must output how many 2-point throws and how many 3-point throws are used.

The input is a single integer n, representing the exact score we want to reach. The output is either a pair (a, b) meaning a throws of 2 points and b throws of 3 points achieve exactly n, and this combination uses the smallest possible number of total throws, or the string No if no such combination exists.

The constraint n ≤ 10^9 immediately rules out any solution that tries to iterate over all possible counts of throws in a naive way. Even a double loop over possible counts of 2-point and 3-point throws would be far too slow in the worst case, since the number of possibilities grows linearly with n.

A subtle edge case appears when small values of n cannot be formed exactly. For example, n = 1 clearly cannot be represented as 2a + 3b, so the correct output is No. Similarly, n = 2 works trivially as (1, 0), and n = 3 as (0, 1). Another non-obvious issue is that greedy choices like “use as many 3-pointers as possible” may fail to give the minimal number of throws or even fail to reach the target even when a valid representation exists.

Approaches

A brute-force approach would try all pairs (a, b) such that 2a + 3b = n. For each possible value of a from 0 to n // 2, we check whether (n - 2a) is divisible by 3. If so, we compute b = (n - 2a) / 3 and track the solution with minimal a + b.

This is correct because it explicitly enumerates every valid decomposition. However, it requires iterating up to O(n) values of a, and for each we do constant work. With n up to 10^9, this becomes completely infeasible.

The key observation is that minimizing the number of throws means maximizing the number of 3-point throws, since each 3-point throw gives more points per operation than a 2-point throw. However, we cannot blindly take n // 3 as the number of 3-point throws because parity constraints may force adjustments. Specifically, after choosing b, the remaining value n - 3b must be even.

This transforms the problem into finding the largest feasible b such that n - 3b ≥ 0 and n - 3b is divisible by 2. Once such a b is found, a is uniquely determined as (n - 3b) / 2.

We only need to check at most a couple of candidates around n // 3, because reducing b by 1 changes the remainder by 3, which flips parity. This guarantees that we find a valid solution quickly if one exists.

Approach Time Complexity Space Complexity Verdict
Brute Force O(n) O(1) Too slow
Optimal O(1) O(1) Accepted

Algorithm Walkthrough

We want to construct n using as many 3-point throws as possible while maintaining validity.

  1. Compute the maximum possible number of 3-point throws as b = n // 3. This gives the largest score contribution from 3-point throws without exceeding n. The remaining points will be handled by 2-point throws.
  2. While b is non-negative, check whether the remaining score n - 3b is divisible by 2. If it is, we have found a valid decomposition. This condition ensures the leftover can be exactly formed using 2-point throws.
  3. If the remainder is not divisible by 2, decrease b by 1 and try again. Reducing b changes the leftover by exactly 3 points, which toggles parity, so a valid solution will appear after at most a small number of adjustments.
  4. If we find such a b, compute a = (n - 3b) // 2 and output (a, b).
  5. If we reduce b below zero without finding a valid configuration, output No.

Why it works

Every valid solution corresponds to an integer pair (a, b) satisfying the linear Diophantine equation 2a + 3b = n. Among all such pairs, minimizing the number of throws is equivalent to maximizing b, since replacing a 3-point throw with a 2-point throw always increases the total number of throws.

By starting from the largest possible b and decreasing only when necessary, we ensure we never skip a better solution. The parity condition n - 3b ≡ 0 (mod 2) fully characterizes feasibility once b is fixed, so checking successive values of b guarantees correctness.

Python Solution

import sys
input = sys.stdin.readline

def solve():
    n = int(input().strip())

    b = n // 3
    while b >= 0:
        rem = n - 3 * b
        if rem % 2 == 0:
            a = rem // 2
            print(a, b)
            return
        b -= 1

    print("No")

if __name__ == "__main__":
    solve()

The code follows the greedy structure described earlier. We start from the maximum possible number of 3-point throws and only adjust downward when the leftover cannot be represented using 2-point throws. The key implementation detail is computing rem = n - 3 * b and checking parity before dividing, which avoids floating-point or invalid integer division.

The loop is safe because it runs at most n // 3 times in theory, but in practice only a constant number of iterations are needed due to parity alternation.

Worked Examples

Example 1: n = 11

We start with b = 11 // 3 = 3.

b rem = n - 3b rem % 2 Action
3 2 0 valid

We stop immediately with a = 1, b = 3.

This shows that the greedy starting point already yields a valid decomposition, confirming that maximizing 3-point throws can directly produce an optimal solution.

Example 2: n = 1

We start with b = 1 // 3 = 0.

b rem = n - 3b rem % 2 Action
0 1 1 decrease b
- - - terminate

No valid configuration exists.

This demonstrates a case where parity constraints make the remainder impossible to represent using 2-point throws, forcing the algorithm to conclude impossibility.

Complexity Analysis

Measure Complexity Explanation
Time O(1) At most a constant number of checks on b, each check is O(1) arithmetic
Space O(1) Only a few integer variables are used

The solution easily fits within constraints since it performs only a handful of arithmetic operations per test case.

Test Cases

import sys, io

def run(inp: str) -> str:
    sys.stdin = io.StringIO(inp)
    from sys import stdout
    import builtins

    output = []

    def fake_print(*args):
        output.append(" ".join(map(str, args)))

    global print
    old_print = print
    print = fake_print
    try:
        solve()
    finally:
        print = old_print

    return "\n".join(output).strip()

# sample-style checks
# n = 11 -> 1 3 is valid
assert run("11\n") == "1 3"

# n = 0 is not in constraints but sanity check
# n = 1 impossible
assert run("1\n") == "No"

# small valid
assert run("2\n") == "1 0"

# all 3s case
assert run("6\n") == "0 2"

# boundary large even
assert run("1000000000\n") != ""

# edge: just below smallest feasible 2-3 combo boundary
assert run("5\n") in ["1 1", "No"]
Test input Expected output What it validates
11 1 3 typical successful greedy case
1 No impossible small value
2 1 0 minimal valid construction
6 0 2 pure 3-point usage
5 1 1 or No boundary feasibility ambiguity

Edge Cases

For n = 1, the algorithm starts with b = 0, giving remainder 1. Since 1 % 2 != 0, it decreases b to -1 and stops, correctly outputting No. This matches the fact that no combination of 2 and 3 can form 1.

For n = 2, we start with b = 0, remainder is 2, which is divisible by 2, so a = 1 and the output is (1, 0). This confirms the algorithm handles pure 2-point constructions correctly without requiring any 3-point adjustment.

For n = 3, b = 1 yields remainder 0, immediately giving (0, 1). This shows that the algorithm correctly prefers higher-value throws when they fit exactly, producing the minimal number of throws.