运行结果
解题思路
很暴力的模拟题,基本不用数据结构,只要思路不乱,注意l-1就能轻松AC
数据结构方面:一个vector维护已输出的内容,一个循环queue维护需要回溯引用的内容
代码分析
输出容器 output
维护已经输出的内容,用字节对应的整数作为元素
vector output;ll output_length = 0;
函数 CharToInt
将字节转换成整数返回
int CharToInt(char HighByte, char LowByte){int H = ('0'<=HighByte && HighBytevoid PrintInt(int x){int H = x / 16, L = x % 16;char HighByte = (0<=H && H<=9) ? H+'0' : H+'a'-10;char LowByte = (0<=L && L<=9) ? L+'0' : L+'a'-10;cout<<HighByte<<LowByte;if(++output_length % 8 == 0)cout<<endl;}
函数Print_ConstData
读取并输出指定长度的字面量
void Print_ConstData(ll const_l){char HighByte, LowByte;while(const_l--) {cin>>HighByte>>LowByte;int Byte = CharToInt(HighByte, LowByte);PrintInt(Byte);output.push_back(Byte);}}
函数Print_VarData
根据o和l输出指定长度的回溯引用,这里维护了一个循环队列,循环输出指定长度的内容
void Print_VarData(ll var_o, ll var_l){queue var_output;for(ll i=0; i<var_o && i<var_l; ++i)var_output.push(output[output_length-var_o+i]);while(var_l--) {int var = var_output.front();PrintInt(var);output.push_back(var);var_output.pop();var_output.push(var);}}
主函数变量定义
HighByte、LowByte、Byte存储读取到的字节和对应的整数
state记录当前的状态:“guide”意为接下来读的字节属于导引域;“finish”意为告一段落,该读入新的数据域了;“const_guide”意为接下来读的字节属于字面量的说明部分;“var_guide_1”意为接下来读的字节属于回溯引用说明部分中的形式1;“var_guide_2”意为接下来读的字节属于回溯引用说明部分中的形式2
guide_length记录导引域的字节数;data_length记录从导引域解析出来的原始数据的长度
const_l记录接下来的字面量的字节数;当l>60时,const_guide_length记录接下来有几个字节算作字面量的说明部分,const_guide_length_i记录已经读了几个字节的字面量的说明部分
var_o、var_l即题中的,var_guide_length和var_guide_length_i的作用同上面的
int main(){ios::sync_with_stdio(false);cin.tie(0);char HighByte, LowByte;int Byte;string state = "guide";ll guide_length = 0, data_length = 0;ll const_length = 0, const_guide_length = 0, const_guide_length_i = 0;ll var_o = 0, var_l = 0, var_guide_length = 0, var_guide_length_i = 0;ll s; cin>>s;for(ll s_length=0; s_length>HighByte>>LowByte;Byte = CharToInt(HighByte, LowByte);/*······*/}return 0;}
主函数循环中state为guide的情况
根据当下的字节是否是最后一个导引域的字节来进行更新
if(state == "guide") {if(Byte >= 128)data_length += (Byte-128) * pow(128, guide_length++);else {data_length += Byte * pow(128, guide_length++);state = "finish";}}
主函数循环中state为finish的情况
判断当下的字节属于哪种类型:
1. 若以00结尾,则为字面量:判断l<=60(注意l+1!!!),若是则直接调用Print_ConstData输出;若不是则记录还有多少字节的说明部分,置state
2. 若以01结尾,则为回溯引用形式1:记录var_l和var_o高3位,置state
3.若以10结尾,则为回溯引用形式2:记录var_l和剩余的说明部分,置state
else if(state == "finish") {if(Byte % 4 == 0) {ll l = Byte / 4 + 1;if(l <= 60) {Print_ConstData(l);s_length += l;}else {const_guide_length = l - 60;const_guide_length_i = 0;state = "const_guide";}}else if(Byte % 4 == 1) {var_l = Byte / 4 % 8 + 4;var_o = Byte / 32 * 256;state = "var_guide_1";}else {var_l = Byte / 4 + 1;var_guide_length = 2;var_guide_length_i = 0;state = "var_guide_2";}}
主函数循环中state为const_guide的情况
补充const_l,若已经将说明部分读取完了则先l+1!!!再直接调用Print_ConstData输出,置state
else if(state == "const_guide") {const_l += Byte * pow(256, const_guide_length_i);if(++const_guide_length_i == const_guide_length) {Print_ConstData(++const_l);s_length += const_l;const_l = 0;state = "finish";}}
主函数循环中state为var_guide_1的情况
补充var_o,调用Print_VarData输出,置state
else if(state == "var_guide_1") {var_o += Byte;Print_VarData(var_o, var_l);var_o = var_l = 0;state = "finish";}
主函数循环中state为var_guide_2的情况
补充var_o,若已经将说明部分读取完了则调用Print_VarData输出,置state
else {var_o += Byte * pow(256, var_guide_length_i);if(++var_guide_length_i == var_guide_length) {Print_VarData(var_o, var_l);var_o = var_l = 0;state = "finish";}}
完整代码
#includeusing namespace std;#define ll long longvector output;ll output_length = 0;int CharToInt(char HighByte, char LowByte){int H = ('0'<=HighByte && HighByte<='9') ? HighByte-'0' : HighByte-'a'+10;int L = ('0'<=LowByte && LowByte<='9') ? LowByte-'0' : LowByte-'a'+10;return H * 16 + L;}void PrintInt(int x){int H = x / 16, L = x % 16;char HighByte = (0<=H && H<=9) ? H+'0' : H+'a'-10;char LowByte = (0<=L && L<=9) ? L+'0' : L+'a'-10;cout<<HighByte<<LowByte;if(++output_length % 8 == 0)cout<>HighByte>>LowByte;int Byte = CharToInt(HighByte, LowByte);PrintInt(Byte);output.push_back(Byte);}}void Print_VarData(ll var_o, ll var_l){queue var_output;for(ll i=0; i<var_o && i>s;for(ll s_length=0; s_length>HighByte>>LowByte;Byte = CharToInt(HighByte, LowByte);if(state == "guide") {if(Byte >= 128)data_length += (Byte-128) * pow(128, guide_length++);else {data_length += Byte * pow(128, guide_length++);state = "finish";}}else if(state == "finish") {if(Byte % 4 == 0) {ll l = Byte / 4 + 1;if(l <= 60) {Print_ConstData(l);s_length += l;}else {const_guide_length = l - 60;const_guide_length_i = 0;state = "const_guide";}}else if(Byte % 4 == 1) {var_l = Byte / 4 % 8 + 4;var_o = Byte / 32 * 256;state = "var_guide_1";}else {var_l = Byte / 4 + 1;var_guide_length = 2;var_guide_length_i = 0;state = "var_guide_2";}}else if(state == "const_guide") {const_l += Byte * pow(256, const_guide_length_i);if(++const_guide_length_i == const_guide_length) {Print_ConstData(++const_l);s_length += const_l;const_l = 0;state = "finish";}}else if(state == "var_guide_1") {var_o += Byte;Print_VarData(var_o, var_l);var_o = var_l = 0;state = "finish";}else {var_o += Byte * pow(256, var_guide_length_i);if(++var_guide_length_i == var_guide_length) {Print_VarData(var_o, var_l);var_o = var_l = 0;state = "finish";}}}return 0;}/*818001240102030405060708090af03c000102030405060708090a0b0c0d0e0f0102030405060708090a0b0c0d0e0f0102030405060708090a0b0c0d0e0f0102030405060708090a0b0c0d0e0fc603000d78*/