CF 1167A - Telephone Number
We are given a string of digits and we are allowed to delete characters freely, without changing the relative order of the remaining digits. The task is to decide whether we can extract a subsequence of length exactly 11 that forms a valid telephone number.
Rating: 800
Tags: brute force, greedy, strings
Solve time: 2m 3s
Verified: yes
Solution
Problem Understanding
We are given a string of digits and we are allowed to delete characters freely, without changing the relative order of the remaining digits. The task is to decide whether we can extract a subsequence of length exactly 11 that forms a valid telephone number. A valid telephone number has a very specific structure: it must have length 11 and its first digit must be 8. The remaining 10 digits can be anything.
So the problem reduces to checking whether the string contains a subsequence of length 11 where the first chosen character is 8.
The constraint on each test case is small, with the string length up to 100 and up to 100 test cases. This immediately rules out any need for heavy preprocessing or advanced data structures. A linear scan per test case is easily sufficient.
A naive but common mistake is to assume we just need to check whether the string contains at least one 8 and at least 10 more digits somewhere after it. This is close but incorrect if not handled carefully in order, because subsequence selection depends on positions. Another mistake is trying to build all subsequences of length 11, which explodes combinatorially even at length 100, since there are $\binom{100}{11}$ possibilities.
A subtle edge case arises when there are multiple 8s. For example, in 88888888888, any position works as a start, but in a string where the first 8 is too late, we might not have enough characters after it. A greedy scan must correctly account for the remaining available length.
Approaches
The brute-force idea is straightforward: generate every subsequence of length 11 and check whether any of them starts with 8. This is correct because it explores all possible deletions. However, the number of subsequences grows rapidly. Even for a single test case with $n = 100$, the number of length-11 subsequences is astronomically large, making this approach infeasible.
The key observation is that we do not need to construct subsequences explicitly. We only need to know whether there exists a position of an 8 such that at least 10 characters come after it in the string. Since deletions preserve order, once we pick an 8 at index i, we only need to verify that there are at least 10 more characters after index i. Those characters can be anything; we simply take them as they appear.
This reduces the problem to scanning for a valid starting position and counting remaining length.
| Approach | Time Complexity | Space Complexity | Verdict |
|---|---|---|---|
| Brute Force (all subsequences) | O(2^n) | O(11) | Too slow |
| Greedy scan from each 8 | O(n) | O(1) | Accepted |
Algorithm Walkthrough
We process each test case independently.
- Read the string and scan through all positions where the digit is
8. Each such position is a candidate start of a telephone number. - For each index
iwheres[i] == '8', check whether the suffix lengthn - iis at least 11. This ensures we can pick 11 characters starting from this8while preserving order. - If any such position satisfies the condition, immediately conclude that a valid subsequence exists.
- If no valid starting position is found, output
NO.
The reasoning behind step 2 is that once we fix the first digit as 8, we only need 10 additional characters after it. Since we are not constrained by their values, only their availability matters.
Why it works
The algorithm relies on a monotonic availability property: if an 8 appears at index i, then every character after it is eligible to be part of the subsequence, and we only need 10 of them. There is no benefit in skipping earlier valid 8s if a later one works, because earlier positions always give at least as many remaining characters. This guarantees that checking positions is sufficient without constructing subsequences.
Python Solution
import sys
input = sys.stdin.readline
t = int(input())
for _ in range(t):
n = int(input())
s = input().strip()
ok = False
for i in range(n):
if s[i] == '8' and n - i >= 11:
ok = True
break
print("YES" if ok else "NO")
The solution iterates over each test case and checks all positions where the digit is 8. The key implementation detail is the condition n - i >= 11, which ensures we can pick the current 8 plus at least 10 following characters. The early exit prevents unnecessary scanning once a valid position is found.
A common mistake is forgetting that the chosen subsequence must preserve order, so only suffix availability matters, not global counts.
Worked Examples
Example 1
Input:
13
7818005553535
We scan positions:
| i | s[i] | is '8'? | n - i | valid start? |
|---|---|---|---|---|
| 0 | 7 | no | 13 | no |
| 1 | 8 | yes | 12 | yes |
At index 1, we have enough characters remaining to form length 11. We can pick 8 at index 1 and then any 10 following digits. So the answer is YES.
This shows that we do not need to explicitly construct the subsequence; availability alone determines feasibility.
Example 2
Input:
11
31415926535
| i | s[i] | is '8'? | n - i | valid start? |
|---|---|---|---|---|
| all | - | no | - | no |
There is no digit 8 in the string, so no valid starting point exists. The result is NO.
This confirms that absence of the required leading digit immediately invalidates the construction.
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(n) per test case | Single linear scan over the string |
| Space | O(1) | Only a few variables used |
Given that $n \le 100$ and $t \le 100$, the solution performs at most $10^4$ operations, which is well within limits.
Test Cases
import sys, io
def run(inp: str) -> str:
sys.stdin = io.StringIO(inp)
input = sys.stdin.readline
t = int(input())
out = []
for _ in range(t):
n = int(input())
s = input().strip()
ok = False
for i in range(n):
if s[i] == '8' and n - i >= 11:
ok = True
break
out.append("YES" if ok else "NO")
return "\n".join(out)
# provided samples
assert run("2\n13\n7818005553535\n11\n31415926535\n") == "YES\nNO"
# custom cases
assert run("1\n11\n80000000000\n") == "YES"
assert run("1\n11\n70000000000\n") == "NO"
assert run("1\n12\n888888888888\n") == "YES"
assert run("1\n20\n12345678901234567890\n") == "NO"
| Test input | Expected output | What it validates |
|---|---|---|
| single valid exact construction | YES | minimal valid case |
| no 8 present | NO | mandatory leading digit |
| all 8s | YES | multiple valid starts |
| no valid structure | NO | general negative case |
Edge Cases
A key edge case is when the string contains an 8, but it appears too late to allow 10 remaining characters. For example, in 11111111118, the only 8 is at the last position. Even though the required digit exists, there are no remaining characters to complete length 11, so the correct answer is NO. The algorithm handles this by explicitly checking suffix length, not just presence of 8.
Another edge case is when multiple 8s exist. The first valid 8 is sufficient to decide success. The scan naturally handles this because it stops at the first position satisfying the suffix condition.