CSP-2023-05-3(解压缩)

文章介绍了如何使用位运算加速程序并提供了一些C++编程技巧,如避免混合使用`std::ios::sync_with_stdio`和输入输出函数,以及如何将十六进制转换为二进制和反之。程序展示了处理数据流和执行特定操作的方法,如ZML和HS算法。
  • 改成位运算可以更好地进行加速和节省空间

  • 其次方法是用string和stoi进行模拟

  • 血泪教训!ios::sync_with_stdio(false)之后千万不要getchar()cinprintf()混着用

    #include <bits/stdc++.h>
    #define endl '\n'
    typedef long long ll;
    using namespace std;
    vector<string> data;
    vector<string> res;
    ll total;
    #pragma GCC optimize(2)
    string hexToB(string s) {
        ll decimal = stoll(s, nullptr, 16);
        stringstream ss; string val;
        ss << bitset<8>(decimal);
        ss >> val;
        return val;
    }
    ll beginNum() {
        vector<ll> C; 
        ll returnVal;
        for (ll i = 0; i < data.size(); ++i) {
            if (data[i][0] == '1') {
                string tmp = data[i];
                tmp[0] = '0';
                C.push_back(stoll(tmp, nullptr, 2));
            } else {
                string tmp = data[i];
                C.push_back(stoll(tmp, nullptr, 2));
                returnVal = i;
                break;
            }
        }
        for (ll i = 0; i < C.size(); ++i) {
            total += (ll)pow(128, i) * C[i]; 
        }
        return returnVal + 1;
    }
    
    ll dealZML(ll begin) {
        ll l = (stoll(data[begin], nullptr, 2) >> 2) + 1;
        if (l < 60) {
            for (ll i = begin+1; i <= begin+l; ++i) {
                res.push_back(data[i]);
            }
            return  begin + l;
        } else if (l > 60) {
            ll num = l - 60;
            string tmp = "";
            for (ll i = begin + num; i >= begin + 1; --i) {
                tmp += data[i];
            }
            ll totalnum = stoll(tmp, nullptr, 2) + 1;
            for (ll i = begin + num + 1; i <= begin + num + totalnum; ++i) {
                res.push_back(data[i]);
            }
            return begin + num + totalnum;
        }
        return 0;
    }
    void HS(ll o, ll l) {
        if (o >= l) {
            ll tmp = res.size();
            for (ll i = tmp - o; i < tmp - o + l; ++i) {
                res.push_back(res[i]);
            }
        } else {
            ll cnt = 0;
            ll tmp = res.size();
            for (ll i = tmp - o; i < tmp; ++i) {
                res.push_back(res[i]);
                cnt++;
                if (cnt == l) break;
                if (i == tmp-1) i = tmp-o-1;
            }
        }
    }
    ll dealHS1(ll begin) {
        string offset = "";
        offset += data[begin][0]; offset += data[begin][1]; offset += data[begin][2];
        offset += data[begin+1];
        ll o = stoll(offset, nullptr, 2);
        string len = "";
        len += data[begin][3]; len += data[begin][4]; len += data[begin][5];
        ll l = stoll(len, nullptr, 2) + 4;
        HS(o, l);
        return begin + 1;
    }
    ll dealHS2(ll begin) {
        string offset = "";
        offset += data[begin+2]; offset += data[begin+1];
        ll o = stoll(offset, nullptr, 2);
        ll l = (stoll(data[begin], nullptr, 2) >> 2) + 1;
        HS(o, l);
        return begin + 2;
    }
    void init() {
        ll n; cin >> n; getchar();
        char ch;
        for (ll i = 0; i < n; ++i) {
            if (i%8 == 0 && i != 0) getchar();
            string s = "";
            for (ll j = 0; j < 2; ++j) {
                ch = getchar();
                s += ch;
            }
            data.push_back(hexToB(s));
        }
    }
    string bToHex(string s) {
        ll decimal = stoll(s, nullptr, 2);
        stringstream ss; string val;
        ss << hex << setw(2) << setfill('0') << decimal;
        ss >> val;
        return val;
    }
    void solve() {
        init();
        ll start = beginNum();
        for (ll i = start; i < data.size(); ++i) {
            if (data[i][6] == '0' && data[i][7] == '0') {
                i = dealZML(i);
            } else if (data[i][6] == '0' && data[i][7] == '1') {
                i = dealHS1(i);
            } else if (data[i][6] == '1' && data[i][7] == '0') {
                i = dealHS2(i);
            }
        }
        for (ll i = 0; i < res.size(); ++i) {
            if (i % 8 == 0 && i != 0) cout << endl;
            cout << bToHex(res[i]);
        }
    }
    int main() {
        // ios::sync_with_stdio(false);
        // cin.tie(0);
        solve();
        return 0;
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值