• 建议
  • 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 条评论

  • @ 2025-5-3 10:55:25

    整体思路

    此代码的功能是对输入的正整数进行变长编码,并以十六进制形式输出编码结果。具体步骤如下:

    1. 把输入的十进制正整数转换为二进制数。
    2. 把二进制数按每 7 位一组进行划分,不足 7 位的在高位补 0。
    3. 从低位组开始,为每组添加最高位,若为最后一组则最高位填 0,否则填 1。
    4. 把每组二进制数转换为 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;
    }
    

    代码各部分详细解释

    1. 头文件和全局变量

      • #include<iostream>:用于输入输出操作。
      • #include<vector>:用于使用 vector 容器。
      • #include<cmath>:用于使用 pow 函数。
      • vector<int> vec:存储转换后的二进制数。
      • vector<int> arr[10]:存储分组后的二进制数。
    2. to16 函数

      • 功能是把 4 位二进制数转换为 1 位十六进制字符。
      • 借助 pow 函数计算 4 位二进制数对应的十进制值,再从 HEXSTR 中获取对应的十六进制字符。
    3. main 函数

      • 输入读取:使用 cin 读取输入的正整数 n
      • 十进制转二进制:通过循环不断取余数和整除 2,将结果存入 vec
      • 高位补 0:计算不足 7 位的位数,在 vec 中补 0。
      • 分组:把 vec 中的二进制数按每 7 位一组存入 arr
      • 添加最高位:遍历 arr,最后一组最高位填 0,其他组填 1。
      • 转换为十六进制输出:遍历 arr,每组 8 位二进制数分成两个 4 位,调用 to16 函数转换为十六进制字符,输出结果。

    复杂度分析

    • 时间复杂度O(logn)O(log n),主要是十进制转二进制的时间开销。
    • 空间复杂度O(logn)O(log n),主要用于存储二进制数。
    • @ 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