本题包括:
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进制对应的数字和字母都放在字符串中,方便读取
如果大家有不懂的,或者文章有何不正,都欢迎评论留言进行讨论或者私信作者