CSP 202305-3 解压缩

黎 浩然/ 14 8 月, 2023/ 算法/ALGORITHMS/ 0 comments

Java:80/100 (内存超限)

import java.util.Scanner;

public class Main {

    public static String hexByte2binByte(String hexString, int index) {
        StringBuilder binByte = new StringBuilder(Integer.toBinaryString(Integer.parseInt(hexString.substring(index, index + 2), 16)));
        while (binByte.length() < 8) {
            binByte.insert(0, "0");
        }
        return binByte.toString();
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder compressedData = new StringBuilder();
        int compressDataLength = scanner.nextInt();
        while (compressedData.length() < compressDataLength * 2) {
            compressedData.append(scanner.next());
        }

        int o, l, i, length; // 避免内存重复分配
        int power = 0;
        int index = 0; // 当前处理到的压缩数据的索引
        int originalDataLength = 0; //原始数据长度
        String binByte = null; // 避免内存重复分配
        StringBuilder originalData = new StringBuilder();

        // 引导区
        for (; index < compressedData.length() && (index == 0 || binByte.charAt(0) != '0'); power += 1, index += 2) {
            binByte = hexByte2binByte(compressedData.toString(), index);
            originalDataLength += Integer.parseInt(binByte.substring(1), 2) * Math.pow(128, power);
        }

        while (index < compressedData.length()) {
            binByte = hexByte2binByte(compressedData.toString(), index);
            if (binByte.charAt(6) == '0' && binByte.charAt(7) == '0') {
                length = Integer.parseInt(binByte.substring(0, 6), 2); // 元素长度 (字节数量)
                if (length < 60) {
                    originalData.append(compressedData.substring(index + 2, index + 2 + 2 * (length + 1)));
                    index += (2 + 2 * (length + 1));
                } else {
                    power = length - 60;
                    length = Integer.parseInt(compressedData.substring(index + 2, index + 4), 16) + 1;
                    for (i = 0; i < power; i++) {
                        length += Integer.parseInt(compressedData.substring(index + 4 + 2 * i, index + 6 + 2 * i), 16) * Math.pow(256, i + 1);
                    }
                    originalData.append(compressedData.substring(index + 4 + 2 * power,index + 4 + 2 * power + 2 * length));
                    index += (4 + 2 * power + 2 * length);
                }
            } else if (binByte.charAt(6) == '0' && binByte.charAt(7) == '1') {
                o = Integer.parseInt(binByte.substring(0, 3), 2) * 256 + Integer.parseInt(compressedData.substring(index + 2, index + 4), 16);
                l = Integer.parseInt(binByte.substring(3, 6), 2) + 4;
                i = originalData.length() - 2 * o;
                for (int j = 0; j < 2 * l; j += 1, i += 1) {
                    originalData.append(originalData.charAt(i));
                }
                index += 4;
            } else if (binByte.charAt(6) == '1' && binByte.charAt(7) == '0') {
                o = Integer.parseInt(compressedData.substring(index + 4, index + 6), 16) * 256 + Integer.parseInt(compressedData.substring(index + 2, index + 4), 16);
                l = Integer.parseInt(binByte.substring(0, 6), 2) + 1;
                i = originalData.length() - 2 * o;
                for (int j = 0; j < 2 * l; j += 1, i += 1) {
                    originalData.append(originalData.charAt(i));
                }
                index += 6;
            }
        }

        for (index = 0; index < originalDataLength * 2; index += 16) {
            System.out.println(originalData.substring(index, Math.min(index + 16, originalDataLength * 2)));
        }
    }
}

C++:100/100

#include <iostream>
#include <string>
#include <sstream>
#include <cmath>
#include <bitset>

std::string hexByte2binByte(const std::string& hexString, int index) {
    int val;
    std::stringstream ss;

    ss << std::hex << hexString.substr(index, 2);
    ss >> val;
    return std::bitset<8>(val).to_string();
}

int main() {

    int o, l, i, length;
    int power = 0;
    int index = 0;
    int compressDataLength = 0;
    int originalDataLength = 0;
    std::string tmp;
    std::string binByte;
    std::string originalData;
    std::string compressedData;

    std::cin >> compressDataLength;
    while (compressedData.length() < compressDataLength * 2) {
        std::cin >> tmp;
        compressedData.append(tmp);
    }

    for (; index < compressedData.length() && (index == 0 || binByte[0] != '0'); power += 1, index += 2) {
        binByte = hexByte2binByte(compressedData, index);
        originalDataLength += std::stoi(binByte.substr(1), nullptr, 2) * (int)std::pow(128, power);
    }

    while (index < compressedData.length()) {
        binByte = hexByte2binByte(compressedData, index);
        if (binByte[6] == '0' && binByte[7] == '0') {
            length = std::stoi(binByte.substr(0, 6), nullptr, 2);
            if (length < 60) {
                originalData.append(compressedData.substr(index + 2, 2 * (length + 1)));
                index += (2 + 2 * (length + 1));
            } else {
                power = length - 60;
                std::stringstream ss;
                ss << std::hex << compressedData.substr(index + 2, 2);
                ss >> length;
                length += 1;

                for (i = 0; i < power; i++) {
                    std::stringstream sst;
                    sst << std::hex << compressedData.substr(index + 4 + 2 * i, 2);
                    int val;
                    sst >> val;
                    length += val * (int)std::pow(256, i + 1);
                }
                originalData.append(compressedData.substr(index + 4 + 2 * power, 2 * length));
                index += (4 + 2 * power + 2 * length);
            }
        } else if (binByte[6] == '0' && binByte[7] == '1') {
            o = std::stoi(binByte.substr(0, 3), nullptr, 2) * 256 + std::stoi(compressedData.substr(index + 2, 2), nullptr, 16);
            l = std::stoi(binByte.substr(3, 3), nullptr, 2) + 4;
            i = (int)(originalData.length() - 2 * o);
            for (int j = 0; j < 2 * l; j += 1, i += 1) {
                originalData += originalData[i];
            }
            index += 4;
        } else if (binByte[6] == '1' && binByte[7] == '0') {
            o = std::stoi(compressedData.substr(index + 4, 2), nullptr, 16) * 256 + std::stoi(compressedData.substr(index + 2, 2), nullptr, 16);
            l = std::stoi(binByte.substr(0, 6), nullptr, 2) + 1;
            i = (int)(originalData.length() - 2 * o);
            for (int j = 0; j < 2 * l; j += 1, i += 1) {
                originalData += originalData[i];
            }
            index += 6;
        }
    }

    for (index = 0; index < originalDataLength * 2; index += 16) {
        std::cout << originalData.substr(index, std::min(16, originalDataLength * 2 - index)) << std::endl;
    }

    return 0;
}
Share this Post

Leave a Comment

您的邮箱地址不会被公开。 必填项已用 * 标注

*
*