这道T3主要是能够读懂题目,然后根据题意进行模拟,需要比较多的位运算,在此题,我选择用uint8_t存储一个字节,然后对字符和数字进行了转换。
#include<bits/stdc++.h>
using namespace std;
uint32_t byteCount = 0;
uint32_t pos = 0;
uint32_t d = 0;
uint32_t totLength = 0;
vector<uint8_t>byteStream;
vector<uint8_t>ansStream;
int main() {
cin >> byteCount;
int lineCount = byteCount / 8;
if(byteCount % 8 != 0) lineCount++;
for(int i = 0; i < lineCount; i++) {
string s; cin >> s;
for(int j = 0; j < s.size(); j += 2) {
uint8_t upper = 0, lower = 0;
if(isdigit(s[j])){upper = s[j] - '0';}
else {upper = s[j] - 'a' + 10; }
if(isdigit(s[j + 1])){lower = s[j + 1] - '0';}
else {lower = s[j + 1] - 'a' + 10;}
byteStream.emplace_back((upper << 4) | lower);
}
}
//处理引导域
while(pos < byteStream.size() && ((byteStream[pos] >> 7) & 1)) {
pos++;
}
pos++;
//继续处理
while(pos < byteStream.size()) {
uint8_t format = (byteStream[pos] & 3);
uint32_t o = 0, l = 0;
if(format == 0) {
l = (byteStream[pos] >> 2) + 1;
if(l <= 60) {
for(int i = 1; i <= l; i++) {
ansStream.push_back(byteStream[pos + i]);
}
pos += (l + 1);
continue;
}
uint32_t offset = l - 60;
l = 0;
for(int i = pos + offset; i > pos; i--) {
l = ((l << 8) | byteStream[i]);
}
l++;
pos += offset;
for(int i = 1; i <= l; i++) {
ansStream.push_back(byteStream[pos + i]);
}
pos += (l + 1);
} else if(format == 1) {
o = (byteStream[pos] >> 5);
o = ((o << 8) | byteStream[pos + 1]);
l = ((byteStream[pos] >> 2) & 7) + 4;
uint32_t p = ansStream.size();
if(o >= l) {
uint32_t begIndex = p - o;
for(int i = 0; i < l; i++) {
ansStream.emplace_back(ansStream[begIndex + i]);
}
} else {
uint32_t begIndex = p - o;
uint32_t cnt = 0;
while(cnt < l) {
int dif = (cnt % o);
ansStream.emplace_back(ansStream[begIndex + dif]);
cnt++;
}
}
pos += 2;
} else {
l = (byteStream[pos] >> 2) + 1;
o = (byteStream[pos + 2]);
o = ((o << 8) | byteStream[pos + 1]);
int p = ansStream.size();
if(o >= l) {
int begIndex = p - o;
for(int i = 0; i < l; i++) {
ansStream.emplace_back(ansStream[begIndex + i]);
}
} else {
int begIndex = p - o;
int cnt = 0;
while(cnt < l) {
int dif = (cnt % o);
ansStream.emplace_back(ansStream[begIndex + dif]);
cnt++;
}
}
pos += 3;
}
}
auto converter = [](uint8_t x)->char {
if(x < 10) return x + '0';
return 'a' + x - 10;
};
for(int i = 0; i < ansStream.size(); i++) {
int lower = (ansStream[i] & 15);
int upper = (ansStream[i] >> 4);
cout << converter(upper) << converter(lower);
if(i > 0 && (i + 1)% 8 == 0) cout << '\n';
}
}