A - 最小の額縁 / Smallest Frame 解説 by admin 印刷ページ
gemini-3-flash-thinkingOverview
This problem asks you to find the smallest rectangle (bounding box) that encloses all painting tiles (#) placed on a grid, and calculate the perimeter of that rectangle.
Analysis
To enclose all painting tiles, we need to determine the following 4 values:
- The row number of the topmost painting tile (\(r_{min}\))
- The row number of the bottommost painting tile (\(r_{max}\))
- The column number of the leftmost painting tile (\(c_{min}\))
- The column number of the rightmost painting tile (\(c_{max}\))
Once these values are determined, the smallest rectangle enclosing all painting tiles has a row range from \(r_{min}\) to \(r_{max}\) and a column range from \(c_{min}\) to \(c_{max}\).
The height of this rectangle can be expressed as \(r_{max} - r_{min} + 1\), and the width as \(c_{max} - c_{min} + 1\). As stated in the problem, the perimeter can be calculated as \(2 \times (\text{height} + \text{width})\).
If no painting tiles exist, there is nothing to enclose, so we output \(0\) as instructed by the problem.
Algorithm
- Initialize variables \(r_{min}, r_{max}, c_{min}, c_{max}\) to track the minimum and maximum positions of painting tiles.
- Examine each cell \((r, c)\) of the grid in order.
- If cell \((r, c)\) is a painting tile (
#):- Update \(r_{min}\) with the minimum of itself and \(r\)
- Update \(r_{max}\) with the maximum of itself and \(r\)
- Update \(c_{min}\) with the minimum of itself and \(c\)
- Update \(c_{max}\) with the maximum of itself and \(c\)
- Set a flag indicating “a painting tile was found”
- After checking all cells, if the flag is not set, output
0. - If the flag is set, calculate the perimeter from the obtained minimum and maximum values and output it.
Complexity
- Time complexity: \(O(H \times W)\)
- Since we scan all cells of the grid exactly once, the time is proportional to the total number of cells. With \(H, W \leq 1000\), this results in at most about \(10^6\) operations, which runs sufficiently fast.
- Space complexity: \(O(H \times W)\)
- Memory proportional to the total number of cells is used to store the input grid information.
Implementation Notes
Efficient search: For each row, using
find('#')(leftmost) andrfind('#')(rightmost) allows us to determine the column range more efficiently than checking each character individually.Initial value setting: Setting \(r_{min}\) and \(c_{min}\) to sufficiently large values, and \(r_{max}\) and \(c_{max}\) to sufficiently small values (or \(-1\), etc.) ensures smooth updates when the first tile is found.
Exception handling: Handle the case where no painting tiles exist by checking something like
if not found:to correctly output \(0\).Source Code
import sys
def solve():
# Read all input data from standard input and split by whitespace
try:
input_data = sys.stdin.read().split()
except EOFError:
return
if not input_data:
return
# H (number of rows) and W (number of columns) are the first two values
try:
H = int(input_data[0])
W = int(input_data[1])
except (ValueError, IndexError):
return
# The grid characters start from index 2 in input_data.
# We join all parts to handle cases where rows might be split by whitespace.
# This creates a single string containing all '#' and '.' characters in order.
all_chars = "".join(input_data[2:])
# Initialize the bounding box boundaries for '#' characters
# r_min, r_max for row indices; c_min, c_max for column indices
r_min, r_max = H, -1
c_min, c_max = W, -1
found = False
# Iterate through the grid row by row
for r in range(H):
# Extract the r-th row from the combined string
# Each row is expected to have exactly W characters.
row = all_chars[r * W : (r + 1) * W]
# Find the first and last occurrence of '#' in the current row
first_idx = row.find('#')
if first_idx != -1:
found = True
last_idx = row.rfind('#')
# Update the global bounding box coordinates
if r < r_min:
r_min = r
if r > r_max:
r_max = r
if first_idx < c_min:
c_min = first_idx
if last_idx > c_max:
c_max = last_idx
if not found:
# If no painting tile '#' was found, the perimeter is 0
print(0)
else:
# The number of rows and columns covered by the bounding box
# height = r2 - r1 + 1, width = c2 - c1 + 1
height = r_max - r_min + 1
width = c_max - c_min + 1
# The perimeter is 2 * (height + width)
# This matches the formula: 2 * ((r2 - r1 + 1) + (c2 - c1 + 1))
print(2 * (height + width))
if __name__ == '__main__':
solve()
This editorial was generated by gemini-3-flash-thinking.
投稿日時:
最終更新: