公式

B - 危険な区域 / Dangerous Areas 解説 by admin

swe-2-high

Dangerous Areas

Problem Summary

There is a grid of \(H\) rows and \(W\) columns, where each cell is either X (dangerous) or . (safe). We must find the topmost row that contains at least one X. If no row contains an X, output -1.

Algorithm

Scan the rows from top to bottom, from row \(1\) to row \(H\), and check whether each row contains an X. The first time a row containing X is found, output its 1-indexed row number and stop. If no X is found after scanning all rows, output -1.

The implementation is straightforward:

  • In C++, we test S.find('X') != string::npos.
  • In Python, we test 'X' in s.

We initialize the answer variable ans to -1 and overwrite it when the first such row is found (C++), or break out of the loop upon finding it, leaving ans at its initial value -1 otherwise (Python).

Proof of Correctness

Lemma: The algorithm outputs row \(i\) if and only if row \(i\) contains an X and none of rows \(1\) through \(i-1\) contain an X.

Proof: The loop inspects rows in the order \(i = 1, 2, \ldots\). If it outputs at row \(i\), that row contains an X. Moreover, the loop continued past rows \(1, \ldots, i-1\), which means none of them contained an X. Conversely, for the smallest row index \(i\) satisfying the condition, the loop is not stopped before reaching it, so it necessarily reaches row \(i\) and outputs it there.

Theorem: The algorithm produces the correct output.

Proof: By the lemma, when some row contains an X, the algorithm outputs the smallest such row index, which matches the statement’s definition of “the first row found when scanning from the top that contains a dangerous area.” When no row contains an X, the loop finishes without ever stopping early and the initial value -1 is printed, which also matches the specification.

Complexity

  • Time: \(O(HW)\). Each row is examined at most once, and checking a row takes \(O(W)\). In practice the scan stops at the first row containing X, so it may be faster.
  • Space: The C++ version discards each row after reading it, using \(O(W)\) auxiliary space. The Python version reads all input at once, using \(O(HW)\). Either way, since \(H, W \leq 10\), this is not an issue.

Tie-breaking

If multiple rows contain X, the algorithm outputs the first one found when scanning from the top, i.e., the smallest row index. This is exactly what the statement requires; no additional tie-breaking rule is needed.