AcWing 5083. 解压缩
原题链接
中等
作者:
Cok
,
2024-09-13 21:03:49
,
所有人可见
,
阅读 10
#include <bits/stdc++.h>
using namespace std;
int n;
string cpr;
string res;
int to_num(char c)
{
if (c >= '0' && c <= '9') return c - '0';
else return c - 'a' + 10;
}
string base2(char c)
{
string res = "";
int t = to_num(c), d = 8;
while (d)
{
if (t >= d)
{
res += "1";
t -= d;
}
else
{
res += "0";
}
d >>= 1;
}
return res;
}
string base2(int idx) // 将一个字节的内容转换为2进制
{
char c1 = cpr[idx], c2 = cpr[idx + 1];
return base2(c1) + base2(c2);
}
int base10(int idx) // 将一个字节的内容转换为10进制
{
char c1 = cpr[idx], c2 = cpr[idx + 1];
int t1 = to_num(c1), t2 = to_num(c2);
return t1 * 16 + t2;
}
int base10(string s) // 将2进制转换为10进制
{
int res = 0;
for (auto c : s)
{
res *= 2;
if (c == '1') res += 1;
}
return res;
}
void proc(string s)
{
// 解析头
int idx = 0, len = 0, c;
while (s[idx] >= '8' || s[idx] >= 'a' && s[idx] <= 'f')
{
c = base10(idx) - 128;
len += c * (int)pow(128, idx / 2);
idx += 2;
}
c = base10(idx);
len += c * (int)pow(128, idx / 2);
idx += 2;
while (idx < s.size())
{
string t = base2(idx);
if (t[6] == '0' && t[7] == '0') // 字面量
{
int l = base10(t.substr(0, 6)) + 1;
if (l <= 60)
{
res += s.substr(idx + 2, l * 2);
idx += (l + 1) * 2;
}
else
{
l -= 60; int rl = 0;
idx += 2;
for (int i = 0; i < l; i++)
{
rl += base10(idx) * (int)pow(256, i);
idx += 2;
}
res += s.substr(idx, (++rl) * 2);
idx += rl * 2;
}
}
else // 回溯引用
{
int o, l;
if (t[6] == '0' && t[7] == '1')
{
o = base10(t.substr(0, 3) + base2(idx + 2));
l = base10(t.substr(3, 3)) + 4;
idx += 4;
}
else
{
o = base10(base2(idx + 4) + base2(idx + 2));
l = base10(t.substr(0, 6)) + 1;
idx += 6;
}
if (o >= l)
{
res += res.substr((int)res.size() - 2 * o, 2 * l);
}
else
{
string t2 = res.substr((int)res.size() - 2 * o);
int lt2 = t2.size() / 2;
while (l >= lt2)
{
res += t2;
l -= lt2;
}
res += t2.substr(0, 2 * l);
}
}
}
}
int main()
{
cin >> n;
int lines = n / 8 + 1;
for (int i = 0; i < lines; i++)
{
string t;
cin >> t;
cpr += t;
}
proc(cpr);
int i = 0;
while (i < res.size())
{
cout << res.substr(i, 16) << endl;
i += 16;
}
return 0;
}
优化
将16进制直接准换为10进制,用int
进行存储,再结合位运算,就等价于对2进制进行操作