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.
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.
- Compute the maximum possible number of 3-point throws as
b = n // 3. This gives the largest score contribution from 3-point throws without exceedingn. The remaining points will be handled by 2-point throws. - While
bis non-negative, check whether the remaining scoren - 3bis 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. - If the remainder is not divisible by 2, decrease
bby 1 and try again. Reducingbchanges the leftover by exactly 3 points, which toggles parity, so a valid solution will appear after at most a small number of adjustments. - If we find such a
b, computea = (n - 3b) // 2and output(a, b). - If we reduce
bbelow zero without finding a valid configuration, outputNo.
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.