标准豆 2024-09-14 21:46 采纳率: 66.7%
浏览 15
已结题

CCF-CSP 2023 第三题 解压缩(50%)

以下代码在ccf-csp官网运行通过50%,本人实在找不到bug了,想请教一下大家看看哪里错啦。
题目:http://118.190.20.162/view.page?gpid=T168

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <math.h>

using namespace std;

//const int N = 2000010;

string str;
string result;
int n;
int len = 0;  //数据长度
int cnt = 0; 


int byte[8];

void change(char c, char c2)    //将一个字节 转为 二进制 放到 byte
{
    int num;
    memset(byte, 0, sizeof byte);
    if(c >= '0' && c <= '9') num = c - '0';
    else if(c >= 'a' && c <= 'f') num = c-'a' + 10;

    int x = 4;
    while(x)
    {
        byte[8-x] = num & 1;
        x--;
        num >>= 1;
    }

    if(c2 >= '0' && c2 <= '9') num = c2 - '0';
    else if(c2 >= 'a' && c2 <= 'f') num = c2-'a' + 10;

    x = 4;
    while(x)
    {
        byte[4-x] = num & 1;
        x--;
        num >>= 1;
    }

}

int GetLength(int idx)
{
    while(1)
    {
        char h = str[idx];
        char l = str[idx + 1];
        
        change(h, l);

        if(byte[7] == 1)
        {
            int sum = 0;
            for(int i = 6; i >= 0; --i) sum = sum * 2  + byte[i];
            //len += sum * pow(128, cnt);
            len += sum * (1 << (7 * cnt));  // 相当于 128 的 cnt 次幂
            cnt++;
        }
        else if(byte[7] == 0)
        {
            int sum = 0;
            for(int i = 6; i >= 0; --i) sum = sum * 2  + byte[i];
            //len += sum * pow(128, cnt);
            len += sum * (1 << (7 * cnt));  // 相当于 128 的 cnt 次幂
            cnt++;

            return idx + 2;
        }

        idx += 2;
    }
    
}

int Check(int idx)
{
    while(1)
    {
        char h = str[idx];
        char l = str[idx + 1];

        change(h, l);

        int sum = 0;

        if(byte[0] == 0 && byte[1] == 0)
        {
            for(int i = 7; i >= 2; --i) sum = sum * 2 + byte[i];
            int all = 0;
            if(sum <= 59)   //小于60 高六位表示 l-1 
            {
                for(int i = idx + 2; i <= idx + 2 * (sum + 1) + 1; i++) result += str[i];   //右边界再加一 为了完整输出最后一个字节
                idx += 2 * (sum + 2);
                return idx;
            }
            else if(sum >= 60)
            {
                int j = sum - 59;
                for(int i = 0; i < j; ++i)
                {
                    idx += 2;
                    h = str[idx];
                    l = str[idx + 1];

                    change(h, l);

                    sum = 0;
                    

                    for(int i = 7; i >= 0; --i) sum = sum * 2 + byte[i];

                    
                    all += sum * pow(128, i);
                }
                for(int i = idx + 2; i <= idx + 2 * (all + 1) + 1; i++) result += str[i];
                idx += 2 * (all + 2);
                return idx;
                
            }
  
        }
        else if(byte[0] == 1 && byte[1] == 0)
        {
            int o = 0, lsb = 0;
            for(int i = 4; i >= 2; --i) sum = sum * 2 + byte[i];

            lsb = sum + 4;              //得到lsb
            for(int i = 7; i >= 5; --i) o = o * 2 + byte[i];

            idx += 2;
            h = str[idx];
            l = str[idx + 1];

            change(h, l);

            for(int i = 7; i >= 0; --i) o = o * 2 + byte[i]; //得到o

            int temidx = result.length() - 1 - 2 * (o - 1) - 1;

            if(o >= lsb)
            {
                for(int i = temidx; i < temidx + 2 * lsb ; ++i) result += result[i];
            }
            else
            {
                int py = 0;
                while(lsb--)
                {
                    result += result[temidx + py];
                    result += result[temidx + py + 1];
                    py+=2;
                    py %= (o*2);
                }
            }

            return idx + 2;

        }
        else if(byte[0] == 0 && byte[1] == 1)
        {
            int o = 0, lsb = 0;
            for(int i = 7; i >= 2; --i) sum = sum * 2 + byte[i];

            lsb = sum + 1;              //得到l


            idx += 2;
            h = str[idx];
            l = str[idx + 1];

            change(h, l);

            sum = 0;
            for(int i = 7; i >= 0; --i) sum = sum * 2 + byte[i];
            o += sum;     

            idx += 2;
            h = str[idx];
            l = str[idx + 1];

            change(h, l);

            sum = 0;
            for(int i = 7; i >= 0; --i) sum = sum * 2 + byte[i];
            o += sum * 128;     //得到o

            int temidx = result.length() - 1 - 2 * (o - 1) - 1;

            if(o >= lsb)
            {
                for(int i = temidx; i < temidx + 2 * lsb ; ++i) result += result[i];
            }
            else
            {
                int py = 0;
                while(lsb--)
                {
                    result += result[temidx + py];
                    result += result[temidx + py + 1];
                    py+=2;
                    py %= (o*2);
                }
            }

            return idx + 2;
        }
        else return -1;

    }



}

int main()
{
    cin >> n;
    str.clear();
    result.clear();
    for(int i = 0; i < n/8 + 1; ++i)
    {
        string ss;
        cin >> ss;
        str += ss;
    }

    int idx = 0;
    
    idx = GetLength(idx);
    n -= idx / 2;

    while(n)
    {
        int ttem = idx;
        idx = Check(idx);
        n -= (idx - ttem) / 2;
        if(result.length() > 65535)
        {
            // 计算需要删除的字符数量
            int excess = result.length() - 65535;
            excess -= excess % 16;
            for(int i = 0; i < excess; ++i)
            {
                cout << result[i];
                if((i + 1) % 16 == 0) cout << endl;
            }
            // 从字符串的开头清空字符
            result.erase(0, excess);
        }

    }    
    for(int i = 0; i < result.length(); ++i)
    {
        cout << result[i];
        if((i + 1) % 16 == 0) cout << endl;
    } 

    return 0;
}

  • 写回答

17条回答 默认 最新

  • micthis 2024-09-15 15:31
    关注

    过了,私我给代码:

    img

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(16条)

报告相同问题?

问题事件

  • 系统已结题 9月24日
  • 已采纳回答 9月16日
  • 创建了问题 9月14日

悬赏问题

  • ¥15 微信小程序 用oss下载 aliyun-oss-sdk-6.18.0.min client报错
  • ¥15 ArcGIS批量裁剪
  • ¥15 labview程序设计
  • ¥15 为什么在配置Linux系统的时候执行脚本总是出现E: Failed to fetch http:L/cn.archive.ubuntu.com
  • ¥15 Cloudreve保存用户组存储空间大小时报错
  • ¥15 伪标签为什么不能作为弱监督语义分割的结果?
  • ¥15 编一个判断一个区间范围内的数字的个位数的立方和是否等于其本身的程序在输入第1组数据后卡住了(语言-c语言)
  • ¥15 Mac版Fiddler Everywhere4.0.1提示强制更新
  • ¥15 android 集成sentry上报时报错。
  • ¥15 抖音看过的视频,缓存在哪个文件