Quick actions

cmd+k|ctrl+k

Navigation

Languages

欲压丁真

Snippet info

Language

Cpp

Visibility

public

Author

dogdie233

Created

2025-05-13T07:44:49.234433Z

Updated

2025-05-19T13:26:14.268755Z

#include <iostream>
#include <vector>
#include <cstdint>
#include <functional>

void compress(const std::vector<uint8_t>& source, std::vector<uint8_t>& result) {
    result.clear();
    if (source.empty()) {
        return;
    }

    ptrdiff_t windowStart = 0;
    bool isContinuous = false;

    using ResolveFunc = std::function<void(int)>;
    ResolveFunc resolveDiscontinuous = [&](int endIndex) -> void {  // 处理不连续部分
        // 使用模式0,填入[length, ...source[windowStart .. idx]]
        result.push_back(endIndex - windowStart);
        result.insert(result.end(), source.begin() + windowStart, source.begin() + endIndex);
        windowStart = endIndex;
    };
    ResolveFunc resolveContinuous = [&](int endIndex) -> void {  // 处理连续部分
        // 使用模式1,填入[0x80 | length, source[windowStart]]
        result.push_back(0x80 | (endIndex - windowStart));
        result.push_back(source[windowStart]);
        windowStart = endIndex;
    };

    for (ptrdiff_t idx = 1; idx < source.size(); idx++) {
        if (source[idx] == source[idx - 1]) {
            if (!isContinuous) {
                // 不连续段结束
                isContinuous = true;
                if (idx - windowStart > 1) {
                    resolveDiscontinuous(idx - 1);
                }
                continue;
            }
        } else {
            if (isContinuous) {
                // 连续段结束,使用模式1
                isContinuous = false;
                resolveContinuous(idx);
                continue;
            }
        }

        if (idx - windowStart == 0x7F) {
            // 超过最大长度了,需要截断
            (isContinuous ? resolveContinuous : resolveDiscontinuous)(idx);
        }
    }

    // 处理剩下的
    (isContinuous ? resolveContinuous : resolveDiscontinuous)(source.size());
}

int main() {
#ifdef ONLINE_JUDGE
    std::ios::sync_with_stdio(0);
    std::cin.tie(0);
#endif

    size_t length;
    std::cin >> length;
    auto source = std::vector<uint8_t>(length);
    auto compressed = std::vector<uint8_t>();

    for (auto& v : source) {
        int num;
        std::cin >> num;
        v = static_cast<uint8_t>(num);
    }

    compress(source, compressed);
    
    std::cout << compressed.size() << '\n';
    for (auto& v : compressed) {
        std::cout << static_cast<int>(v) << ' ';
    }
}
INFO