压缩技术(续集版)

GitHub跳转原题关系图返回列表

把输入矩阵按行拼成一维字符串,从 0 开始统计交替游程长度并输出压缩码。

OJ: luogu

题目 ID: P1320

难度:入门

标签:模拟字符串python

日期: 2026-07-15 18:58

题意

输入一个 n * n01 矩阵,要求输出它的压缩码。压缩码第一个数是 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 开头则先补一段长度为 00

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)

复杂度

每个矩阵字符处理一次,时间复杂度是 O(n2)O(n^2),保存输入和压缩结果需要 O(n2)O(n^2) 空间。

总结

压缩题的关键是始终从 0 的游程开始统计。先拼成一维字符串,再做游程编码,逻辑最清楚。