把输入矩阵按行拼成一维字符串,从 0 开始统计交替游程长度并输出压缩码。
OJ: luogu
题目 ID: P1320
难度:入门
标签:模拟字符串python
日期: 2026-07-15 18:58
题意
输入一个 n * n 的 01 矩阵,要求输出它的压缩码。压缩码第一个数是 n,后面从连续 0 的个数开始,交替记录连续 1、连续 0 的长度。
思路
先把所有输入行拼成一个一维字符串 text。然后从当前字符 "0" 开始统计。
如果当前读到的字符等于 current,计数加一;否则说明当前游程结束,把计数加入答案,再切换 current,重新从 1 开始计数。
注意:即使矩阵第一个字符是 1,压缩码也必须先输出连续 0 的个数,也就是 0。
这题是游程编码练习,不创建 brute.py。
Python 知识
/home/rainboy/mycode/hugo-blog/content/program_language/python/oj_input_output_cheatsheet.md:不知道行数时,可以读到 EOF。/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:"".join(rows)可以把多行拼成一维字符串。try/except EOFError可以用input()读到文件结束。print(*answer)按空格输出压缩码。
代码
python
rows = []
try:
while True:
rows.append(input().strip())
except EOFError:
pass
n = len(rows[0])
text = "".join(rows)
answer = [n]
current = "0"
count = 0
for ch in text:
if ch == current:
count += 1
else:
answer.append(count)
current = ch
count = 1
answer.append(count)
print(*answer)cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
char line[205]; // 存储每行输入的字符串
int n; // 矩阵大小
int main() {
// 读入第一行,确定 n
cin >> line;
n = strlen(line);
// 把所有行拼成一行字符
string all = line;
for (int i = 2; i <= n; i++) {
cin >> line;
all += line;
}
cout << n << " "; // 先输出矩阵大小
char cur = '0'; // 从 0 的游程开始统计
int cnt = 0;
for (char ch : all) {
if (ch == cur) {
cnt++;
} else {
cout << cnt << " ";
cur = ch;
cnt = 1;
}
}
cout << cnt; // 最后一段游程
return 0;
}Pythonic 写法
用 groupby 做游程编码;若以 1 开头则先补一段长度为 0 的 0:
python
from itertools import groupby
import sys
text = "".join(line.strip() for line in sys.stdin if line.strip())
n = int(len(text) ** 0.5)
runs = [len(list(group)) for _, group in groupby(text)]
if text and text[0] == "1":
runs = [0] + runs
print(n, *runs)复杂度
每个矩阵字符处理一次,时间复杂度是
总结
压缩题的关键是始终从 0 的游程开始统计。先拼成一维字符串,再做游程编码,逻辑最清楚。