B3870 [GESP202309 四级] 变长编码(膜拜版)

本题包括:

1.进制的超强使用

2.进制的截位使用

本题参考洛谷题解:https://www.luogu.com.cn/article/daqzhu5m 

 (在线膜拜作者的代码中)

难度:普及-


对于笔者而言:

这道题在洛谷上通过率很高,有大概一半。因为这道题整体而言,思路不难,用辗转相除法还是按照题目给的先转二进制再转十六进制来说,出错率不高

写这篇题解的主要目的是因为:去题解区看到的短小精悍版,思考良久,终觉其精妙无比,题解原作者未写解析,故:帮助看不懂的同学们写一份


先上代码

#include<bits/stdc++.h>
using namespace std;
long long n;
string a="0123456789ABCDEF";//十六进制的数字
void print(int i){//输出
	cout<<a[i/16]<<a[i%16]<<" ";
}
int main(){
	cin>>n;
	if(n==0){cout<<"00";return 0;}//0需要特判
	while(n>0){
		int k=n%128;//2^7=128,7位一截
		n/=128;
		if(n>0)print(k+128);//判断是否为最高位
		else print(k);
	}
	return 0;
}

初见觉得很怪:

为什么n%128之后,n/128?这样的结果为什么成立?

为什么不是最高位的状态,k+128?

以及,为什么最后 i/16

我们一个一个来细讲:

 1. 为什么n%128之后,n/128?这样的结果为什么成立?

因为数据是7位一截,而2的7次方为128,刚好去除128的一截,%为得到后面的数据,/为得到去除%后的数据,这样写不明显,我们用二进制来看一下:

对于数据926

二进制为:111 0011110

七比特为一截的在高位补0:0000111 0011110

得到的十六进制最终结果为:9E  07

如果我们对原数据 %128,得到的就是 0011110

如果我们对原数据 /128,得到的就是 0000111

结果成立,并且与进制不违背

2. 为什么不是最高位的状态,k+128?

因为题目中的第二点规则:

即如果不是最后一组,高位都需要补1

而k+128就是在补1!

 3. 为什么最后 i/16?

这个问题最简单了,是在转16进制,而将16进制对应的数字和字母都放在字符串中,方便读取


如果大家有不懂的,或者文章有何不正,都欢迎评论留言进行讨论或者私信作者 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值