- 建议
B3870 [GESP202309 四级] 变长编码
- 2025-5-1 12:20:28 @
B3870 [GESP202309 四级] 变长编码 https://www.luogu.com.cn/problem/B3870
#include<iostream>
#include<vector>
using namespace std;
vector<int> vec;
vector<int> arr[10];
int main() {
long long n;
cin >> n;
while(n!=0){
vec.push_back(n%2);
n/=2;
}//10 -> 0101000
int len = 7 - vec.size()%7;//20/7=2....6
for(int i=1;i<=len;i++){
vec.push_back(0);
}
len = vec.size() / 7;//21 / 7 -> 3
for(int i=1;i<=len;i++){
for(int j=1;j<=7;j++){
arr[i-1].push_back(vec[(i-1)*7+(j-1)]);
}
}
for(int i=0;i<len;i++){
if(i==len-1){
arr[i].push_back(0);
}else{
arr[i].push_back(1);
}
}
//01111001
//11100000
for(int i=0;i<len;i++){
string res = "";
for(int j = 0;j < 8;j++){
}
}
//......
for(int i=0;i<len;i++){
for(const auto& j:arr[i]){
cout<<j;
}
cout<<endl;
}
return 0;
}
2 条评论
-
admin SU @ 2025-5-3 10:55:25
整体思路
此代码的功能是对输入的正整数进行变长编码,并以十六进制形式输出编码结果。具体步骤如下:
- 把输入的十进制正整数转换为二进制数。
- 把二进制数按每 7 位一组进行划分,不足 7 位的在高位补 0。
- 从低位组开始,为每组添加最高位,若为最后一组则最高位填 0,否则填 1。
- 把每组二进制数转换为 2 位十六进制数输出。
代码解释
#include<iostream> #include<vector> #include<cmath> using namespace std; vector<int> vec; // 用于存储二进制数的每一位 vector<int> arr[10]; // 用于存储分组后的二进制数 // 将 4 位二进制数转换为 1 位十六进制字符的函数 char to16(int a, int b, int c, int d) { // 计算 4 位二进制数对应的十进制值 int t = a * pow(2, 0) + b * pow(2, 1) + c * pow(2, 2) + d * pow(2, 3); string HEXSTR = "0123456789ABCDEF"; // 十六进制字符集 return HEXSTR[t]; // 返回对应的十六进制字符 } int main() { long long n; cin >> n; // 读取输入的正整数 // 将十进制数转换为二进制数 while (n != 0) { vec.push_back(n % 2); // 取余数作为二进制位 n /= 2; // 整除 2 进行下一位计算 } // 示例:10 -> 01010 // 不足 7 位的在高位补 0 int len = 7 - vec.size() % 7; for (int i = 1; i <= len; i++) { vec.push_back(0); } // 按每 7 位一组进行分组 len = vec.size() / 7; for (int i = 1; i <= len; i++) { for (int j = 1; j <= 7; j++) { arr[i - 1].push_back(vec[(i - 1) * 7 + (j - 1)]); } } // 为每组添加最高位 for (int i = 0; i < len; i++) { if (i == len - 1) { arr[i].push_back(0); // 最后一组最高位为 0 } else { arr[i].push_back(1); // 其他组最高位为 1 } } // 将每组二进制数转换为 2 位十六进制数输出 for (int i = 0; i < len; i++) { string res = ""; // 先处理高 4 位 res += to16(arr[i][4], arr[i][5], arr[i][6], arr[i][7]); // 再处理低 4 位 res += to16(arr[i][0], arr[i][1], arr[i][2], arr[i][3]); cout << res << " "; } return 0; }
代码各部分详细解释
-
头文件和全局变量:
#include<iostream>
:用于输入输出操作。#include<vector>
:用于使用vector
容器。#include<cmath>
:用于使用pow
函数。vector<int> vec
:存储转换后的二进制数。vector<int> arr[10]
:存储分组后的二进制数。
-
to16
函数:- 功能是把 4 位二进制数转换为 1 位十六进制字符。
- 借助
pow
函数计算 4 位二进制数对应的十进制值,再从HEXSTR
中获取对应的十六进制字符。
-
main
函数:- 输入读取:使用
cin
读取输入的正整数n
。 - 十进制转二进制:通过循环不断取余数和整除 2,将结果存入
vec
。 - 高位补 0:计算不足 7 位的位数,在
vec
中补 0。 - 分组:把
vec
中的二进制数按每 7 位一组存入arr
。 - 添加最高位:遍历
arr
,最后一组最高位填 0,其他组填 1。 - 转换为十六进制输出:遍历
arr
,每组 8 位二进制数分成两个 4 位,调用to16
函数转换为十六进制字符,输出结果。
- 输入读取:使用
复杂度分析
- 时间复杂度:,主要是十进制转二进制的时间开销。
- 空间复杂度:,主要用于存储二进制数。
-
2025-5-3 10:55:01@
#include<iostream> #include<vector> #include<cmath> using namespace std; vector<int> vec; vector<int> arr[10]; char to16(int a,int b,int c,int d){//0 1 1 1 int t = a*pow(2,0)+b*pow(2,1)+c*pow(2,2)+d*pow(2,3); string HEXSTR = "0123456789ABCDEF"; return HEXSTR[t]; } int main() { long long n; cin >> n; while(n!=0){ vec.push_back(n%2); n/=2; }//10 -> 0101000 int len = 7 - vec.size()%7;//20/7=2....6 for(int i=1;i<=len;i++){ vec.push_back(0); } len = vec.size() / 7;//21 / 7 -> 3 for(int i=1;i<=len;i++){ for(int j=1;j<=7;j++){ arr[i-1].push_back(vec[(i-1)*7+(j-1)]); } } for(int i=0;i<len;i++){ if(i==len-1){ arr[i].push_back(0); }else{ arr[i].push_back(1); } } //0 1 1 1 1 0 0 1 9E //11100000 07 //9E 07 for(int i=0;i<len;i++){ string res = ""; res += to16(arr[i][4],arr[i][5],arr[i][6],arr[i][7]);//1 0 0 1 res += to16(arr[i][0],arr[i][1],arr[i][2],arr[i][3]);//0 1 1 1 cout<<res<<" "; } //...... // for(int i=0;i<len;i++){ // for(const auto& j:arr[i]){ // cout<<j; // } // cout<<endl; // } return 0; }
- 1