📜  门|门 CS 1999 |第 55 题(1)

📅  最后修改于: 2023-12-03 15:28:47.804000             🧑  作者: Mango

题目介绍

本题题目名称为"门|门",是ACM/ICPC的蓝组第55题。

在此题中,你需要实现一个解密程序,将给定的密文解密成明文。

题目详解

题目描述

给定一张由数字0和1组成的$n \times m$的矩阵,代表一扇门的结构。

若该门的密文是$0$,则该位置为空;若该门的密文是$1$,则该位置上有一块木板。

现在,门被人破坏,只有一部分木板还留在门上,其余木板已经丢失。

你需要在这扇门中重建这些缺失的木板,并还原出门的原始结构。门的边缘上已经有连续的木板连接在一起,因此你可以从这些边缘开始还原木板。注意,门的边缘上所有的木板都是完整的,因此你可以假设这些边缘已经还原好了。

需要还原的木板数量不超过$20$,并且至少需要还原$1$块木板。重建完木板后,请输出门的原始结构。

输入格式

第一行包含三个整数:$n$,$m$,$k$,表示矩形的长、宽和缺失的木块数。$(1 \leq n, m \leq 1000, 0 \leq k \leq 20)$

接下来$k$行,每行包含两个整数,表示一块缺失的木板的位置$(x_i, y_i)$。行和列坐标从$1$开始。

输出格式

输出包含$n$行,每行$m$个字符,表示门的原始结构。其中,字符"$0$"表示该位置为空,"$1$"表示该位置上有一块木板。

样例输入
5 5 3
3 3
5 5
5 3
样例输出
00000
00000
01110
00000
01110

题解思路

本题是一道模拟题,需要依次还原每块缺失的木板以还原门的原始结构。解决思路如下:

  1. 读入矩阵,标记所有有木板的位置,初始化矩阵;
  2. 读入所有缺失的木板位置,将这些位置标记为空;
  3. 从已有的木板位置向外进行搜索,遇到标记为空的位置则将其标记为有木板,并将其加入待探索位置列表;
  4. 持续搜索,直至待探索位置列表为空;
  5. 输出还原后的门的结构矩阵。

参考代码

def is_valid(x, y, n, m):
    return x >= 0 and x < n and y >= 0 and y < m

def door_restore(n, m, k, missing_blocks):
    # Step 1: 初始化矩阵,标记所有有木板的位置
    door = [[0] * m for _ in range(n)]
    for block in missing_blocks:
        x, y = block
        door[x-1][y-1] = -1

    # Step 2: 将缺失的木板标记为空
    for block in missing_blocks:
        x, y = block
        door[x-1][y-1] = 0

    # Step 3 & 4: 从已有的木板位置向外搜索,遇到标记为空的位置则标记有木板
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
    start_blocks = [(i, j) for i in range(n) for j in range(m) if door[i][j] == 1]

    explored_blocks = set(start_blocks)
    queue = collections.deque(start_blocks)
    while queue:
        block = queue.popleft()
        x, y = block
        for dx, dy in directions:
            nx, ny = x+dx, y+dy
            if is_valid(nx, ny, n, m) and (nx, ny) not in explored_blocks:
                explored_blocks.add((nx, ny))
                if door[nx][ny] == -1:
                    door[nx][ny] = 1
                    queue.append((nx, ny))

    # Step 5: 输出还原后的门的结构矩阵
    return "\n".join(["".join(["1" if door[i][j] else "0" for j in range(m)]) for i in range(n)])

该函数的输入参数为$n$和$m$表示矩形的长和宽;$k$表示缺失的木板数;$missing_blocks$是一个列表,每个元素为一个位置元组,表示该位置上原来应该有木板,但现在缺失。

函数输出为一个字符串,表示还原后门的结构矩阵。该字符串可以直接输出或写入文件。