CSP-解压缩 C/C++满分题解

大模拟,按照题意一步步写即可

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll lines;
double s;
vector<int> bits;
ll flag;
ll rawlength;
string ans;

int c2i(char c){
	if(c>='0'&&c<='9'){
		return c-'0';
	}else{
		return c-'a'+10;
	}
}

void i2s(int b){
	int curnum = b >> 4;
	for(int i = 0;i<2;i++){
		if(curnum < 10){
			ans.push_back(curnum + '0');
		}else{
			ans.push_back(curnum-10 + 'a');
		}
		curnum = b-(curnum<<4);
	}  
}

void Ireturn(int l){
	ll o = 0;
	for(int i = 0;i<2;i++){
		ll t = bits[flag] << (i*8);
		o += t;
		flag++;
	}
//	printf("<%ld,%ld>\n",o,l);
	if(o>=l){
		int curflag = ans.size() - 2*o;
		for(int i = 0;i<l;i++){
			ans.push_back(ans[curflag+i*2]);
			ans.push_back(ans[curflag+i*2+1]);
		}
	}else{
		int curflag = ans.size() - 2*o;
		int i = 0,j = 0;
		while(i < l){
			if(j == o){
				j = 0;
			}
			ans.push_back(ans[curflag+j*2]);
			ans.push_back(ans[curflag+j*2+1]);
			j++;
			i++;
		} 
	}
}

void IIreturn(int l,int o){
	o <<= 8;
	o += bits[flag];
	flag++;
//	printf("<%d,%d>\n",o,l);
	if(o>=l){
		int curflag = ans.size() - 2*o;
		for(int i = 0;i<l;i++){
			ans.push_back(ans[curflag+i*2]);
			ans.push_back(ans[curflag+i*2+1]);
		}
	}else{
		int curflag = ans.size() - 2*o;
		int i = 0,j = 0;
		while(i < l){
			if(j == o){
				j = 0;
			}
			ans.push_back(ans[curflag+j*2]);
			ans.push_back(ans[curflag+j*2+1]);
			j++;
			i++;
		} 
	}
} 

void solveData(ll length){
	for(ll i = 0;i<length;i++){
		i2s(bits[flag]);
		flag++;
	}
}

void guider(){
	while(bits[flag] >= 128){
		rawlength += ((bits[flag]-128)*pow(128,flag));
		flag++;
	}
	rawlength += (bits[flag]*pow(128,flag));
	flag++;
}	

void judgeType(){
	int lowbit[2];
	int tb = bits[flag];
//	cout << flag << ' ';
	for(int i = 0;i<2;i++){
		lowbit[i] = tb&1;
//		cout << lowbit[i] << ' ';
		tb>>=1;
	}
//	cout << endl;
	if(lowbit[0] == 0&&lowbit[1] == 0){
		if(tb < 60){
			flag++;
			solveData(tb + 1); 
		}else{
			int step = tb-59;
			ll reallength = 0;
			flag++;
			for(int i = 0;i<step;i++){
				ll t = bits[flag]<<(i*8);
				reallength += t;
//				cout << reallength << endl;
				flag++; 
			}
			solveData(reallength + 1);
		}
		//字面量 
	}else{
		if(lowbit[0] == 0){
//			cout << "Type1:" << tb << endl;
			flag++;
			Ireturn(tb+1);
			//10
		}else if(lowbit[1] == 0){
			int l = tb>>3;
			l = tb - (l<<3);//2-4位 
			tb >>= 3;//高三位 
//			cout << "Type2:" << tb << endl;
			flag++;
			IIreturn(l+4,tb);
			//01
		} 
		//回溯 
	} 
}

int main(){
	cin >> s;
	lines = ceil(s/8);
	for(int i = 0;i<lines;i++){
		string t;
		cin >> t;
		int bit = 0; 
		for(int j = 0;j<t.size();j++){
			if(j&1){
				bit += c2i(t[j]);
				bits.push_back(bit);
				bit = 0;
				//低位 
			}else{
				bit += c2i(t[j]);
				bit <<= 4;
				//高位 
			} 
		}
	}
	//TESTDATA
//	for(int i = 0;i<bits.size();i++){
//		if(i%8 == 0){
//			cout << endl;
//		}
//		cout << bits[i] << ' ';
//	}
	guider();
//	cout << rawlength << endl;
	while(flag < bits.size()){
		judgeType();
	}
	for(int i = 0;i<ans.size();i++){
		if(i%16 == 0&&i!=0){
			cout << endl;
		}
		cout << ans[i];
	}
	
}

需要注意有些数据是小端存储,需要转换一下

说明:

int c2i(char c):返回一位字符转换的10进制数
void i2s(int b):int转string,用于解压缩数据转换
void Ireturn(int l):传入l,回溯引用,用于低位为10的情况
void IIreturn(int l,int o):传入l和o的高三位,用于01情况
void solveData(ll length):用于处理字面量
void guider():处理引导
void judgeType():判断字面量/回溯并进行初步处理

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值