1 条题解
-
0
描述
Mo和Larry发明了一种加密消息的方法。他们首先秘密决定列数,然后将消息(仅包含字母)按列写入,并用额外的随机字母填充,以形成一个矩形的字母阵列。例如,如果消息是 “There’s no place like home on a snowy night” 且列数为,Mo会写下:
t o i o y h p k n n e l e a i r a h s g e c o n h s e m o t n l e w x
注意,Mo只包含字母并将它们全部转换为小写。在此示例中,Mo使用字母“x”填充消息以形成矩形,但他也可以使用任何其他字母。
然后,Mo通过按行交替从左到右和从右到左书写字母,将消息发送给Larry。因此,上述消息将被加密为:
toioynnkpheleaigshareconhtomesnlewx
你的任务是为Larry从加密的消息中恢复原始消息(包括任何额外的填充字母)。
输入
每个输入集包含多组数据。每组输入由两行组成。第一行包含一个范围在到之间的整数,表示使用的列数。第二行是一个最多包含个小写字母的字符串。最后一个输入集之后是一行包含单个,表示输入结束。
输出
每个输入集应生成一行输出,给出原始的明文消息,不含空格。
问题重述
Mo和Larry发明了一种加密消息的方法。具体步骤如下:
-
加密过程:
- 首先,他们秘密决定一个列数(例如5)。
- 将原始消息(仅包含字母,且已转换为小写)按列写入,形成一个矩形的字母阵列。如果字母数量不足以填满矩形,则用随机的小写字母填充。
- 然后,按行交替从左到右和从右到左读取字母,形成加密后的字符串。
例如,消息“There’s no place like home on a snowy night”和列数为5时:
- 按列写入:
t o i o y h p k n n e l e a i r a h s g e c o n h s e m o t n l e w x
- 然后按行交替方向读取:
- 第一行从左到右:toioy
- 第二行从右到左:nnkph
- 第三行从左到右:eleai
- 第四行从右到左:gshar
- 第五行从左到右:econh
- 第六行从右到左:tomes
- 第七行从左到右:nlewx
- 组合起来:toioynnkpheleaigshareconhtomesnlewx
-
解密任务:
- 给定列数和加密后的字符串,恢复原始的矩形字母阵列(包括填充字母)。
- 输出原始的明文消息(按列读取)。
输入输出示例
输入:
5 toioynnkpheleaigshareconhtomesnlewx 0
输出: theresnoplacelikehomeonasnowynightx
解题思路
-
理解加密的逆过程:
- 加密时是按行交替方向(左→右,右→左)读取的,因此解密时需要将加密字符串重新拆分成行,并交替方向恢复原始的行内容。
- 然后按列读取原始消息。
-
具体步骤:
- 给定列数
cols
和加密字符串s
。 - 计算行数
rows
:rows = len(s) // cols
(因为总字母数必须为rows * cols
)。 - 将
s
拆分成rows
行,每行cols
个字符。- 第0行:从左到右
- 第1行:从右到左
- 第2行:从左到右
- ...
- 恢复原始矩形:
- 对于偶数行(0-based),直接按顺序填充。
- 对于奇数行(0-based),需要反转后填充。
- 按列读取原始消息:
- 从左到右逐列读取,每列从上到下。
- 给定列数
-
示例解析:
- 输入:
cols = 5
,s = "toioynnkpheleaigshareconhtomesnlewx"
。 len(s) = 35
, 所以rows = 35 / 5 = 7
。- 拆分:
- 第0行:toioy(直接)
- 第1行:nnkph(反转→ hpkn n)
- 第2行:eleai(直接)
- 第3行:gshar(反转→ rahs g)
- 第4行:econh(直接)
- 第5行:tomes(反转→ semo t)
- 第6行:nlewx(直接)
- 恢复矩形:
t o i o y h p k n n e l e a i r a h s g e c o n h s e m o t n l e w x
- 按列读取:
- 第0列:t, h, e, r, e, s, n → "there sn"
- 第1列:o, p, l, a, c, e, l → "oplace l"
- 第2列:i, k, e, h, o, m, e → "ikehome"
- 第3列:o, n, a, s, n, o, w → "onasnow"
- 第4列:y, n, i, g, h, t, x → "ynightx"
- 组合:"theresnoplacelikehomeonasnowynightx"
- 输入:
代码实现
while True: cols = int(input()) if cols == 0: break s = input().strip() rows = len(s) // cols grid = [] for i in range(rows): start = i * cols end = start + cols row_str = s[start:end] if i % 2 == 1: row_str = row_str[::-1] grid.append(list(row_str)) # Read by columns original = [] for c in range(cols): for r in range(rows): original.append(grid[r][c]) print(''.join(original))
代码解释
-
输入处理:
- 循环读取输入,直到遇到
0
为止。 - 对于每组数据,读取列数
cols
和加密字符串s
。
- 循环读取输入,直到遇到
-
恢复矩形:
- 计算行数
rows = len(s) // cols
。 - 初始化
grid
作为二维列表存储矩形。 - 将
s
按行拆分,对于奇数行(0-based)进行反转。
- 计算行数
-
按列读取原始消息:
- 遍历每一列,从上到下依次读取字符,拼接成原始消息。
-
输出:
- 将拼接后的字符列表转换为字符串并输出。
示例运行
输入:
5 toioynnkpheleaigshareconhtomesnlewx 0
输出:
theresnoplacelikehomeonasnowynightx
注意事项
- 确保正确处理行方向的交替(偶数行不反转,奇数行反转)。
- 按列读取时,列优先,行顺序递增。
- 填充字母是原始消息的一部分,无需特别处理。
-
- 1
信息
- ID
- 1040
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者