欲压丁真
#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