LCB-03: Art Gallery on Graph
The Task
Scroll to read full problem statement
The Code
Claude Opus 4.6 with max-effort extended thinking. Exact outputs. Side by side.
Baseline
FAIL1191ch / 11simport sys
from collections import deque
def main():
input = sys.stdin.buffer.read().split()
idx = 0
N = int(input[idx]); idx += 1
M = int(input[idx]); idx += 1
K = int(input[idx]); idx += 1
adj = [[] for _ in range(N + 1)]
for _ in range(M):
a = int(input[idx]); idx += 1
b = int(input[idx]); idx += 1
adj[a].append(b)
adj[b].append(a)
# Multi-source BFS with remaining stamina
# For each vertex, track the max remaining stamina when reached
best = [0] * (N + 1) # best remaining stamina at each vertex
dq = deque()
for _ in range(K):
p = int(input[idx]); idx += 1
h = int(input[idx]); idx += 1
if h > best[p]:
best[p] = h
dq.append((p, h))
# BFS: propagate stamina
while dq:
v, rem = dq.popleft()
if rem < best[v]:
continue
if rem == 0:
continue
for u in adj[v]:
nr = rem - 1
if nr > best[u]:
best[u] = nr
dq.append((u, nr))
guarded = [i for i in range(1, N + 1) if best[i] > 0]
print(len(guarded))
print(*guarded)
main()Scroll to read full code
Augmented
PASS1282ch / 125simport sys
def solve():
data = sys.stdin.buffer.read().split()
idx = 0
N = int(data[idx]); idx += 1
M = int(data[idx]); idx += 1
K = int(data[idx]); idx += 1
adj = [[] for _ in range(N + 1)]
for _ in range(M):
a = int(data[idx]); idx += 1
b = int(data[idx]); idx += 1
adj[a].append(b)
adj[b].append(a)
remaining = [-1] * (N + 1)
max_h = 0
guards = []
for _ in range(K):
p = int(data[idx]); idx += 1
h = int(data[idx]); idx += 1
guards.append((p, h))
if h > max_h:
max_h = h
buckets = [[] for _ in range(max_h + 1)]
for p, h in guards:
if h > remaining[p]:
remaining[p] = h
buckets[h].append(p)
for r in range(max_h, 0, -1):
for v in buckets[r]:
if remaining[v] != r:
continue
for u in adj[v]:
nr = r - 1
if nr > remaining[u]:
remaining[u] = nr
if nr > 0:
buckets[nr].append(u)
result = []
for v in range(1, N + 1):
if remaining[v] >= 0:
result.append(str(v))
sys.stdout.write(str(len(result)) + '\n' + ' '.join(result) + '\n')
solve()Scroll to read full code
Blind Evaluation
Independent evaluator. Randomized A/B labels. No knowledge of which solution used the injection.
Augmented 43, Baseline 22
| Dimension | Baseline | Augmented |
|---|---|---|
| Correctness | 2 | 10 |
| Efficiency | 7 | 8 |
| Code Structure | 6 | 8 |
| Readability | 6 | 8 |
| Robustness | 1 | 9 |
Blind Analysis
Both solutions use multi-source BFS with a "remaining stamina" model: seed each guard's position with its stamina value, then propagate outward, decrementing by 1 per edge. The critical difference lies in initialization and the guarded-vertex predicate. The baseline initializes best to 0 and collects guarded vertices as best[i] > 0. The augmented solution initializes remaining to -1 and collects as remaining[v] >= 0. The defect in The baseline is fatal.
Blind Observation
The bug in The baseline is a classic sentinel collision: using 0 to mean both "unreached" and "reached with zero remaining" collapses two distinct states into one. This is the kind of off-by-one that survives local reasoning ("stamina 0 means you can't go further, so skip") but fails global reasoning ("can't go further does not mean wasn't reached").
Source: LiveCodeBench Hard benchmark. Full code outputs: baseline · augmented · runner script & methodology