1 条题解

  • 0
    @ 2026-10-18 18:37:31

    G4002 [GESP202306 四级] 图像压缩 题解

    知识点:进制转换、频数统计、多关键字排序、模拟。

    解题思路

    将每两个十六进制字符解成一个像素,统计256种值的频次。按频次降序、像素值升序选16项调色板,再为每个像素找差值最小的调色板编号。

    为什么正确

    排序落实调色板选取规则,逐像素穷举16个候选得到最接近颜色;相同距离保留先出现的编号。

    易错点

    颜色用两位大写十六进制输出,压缩后的索引用一位;频次和距离并列规则不能遗漏。

    复杂度

    设像素数P,时间O(P+256log256+16P),空间O(P+256)。

    参考代码(C++17)

    #include<bits/stdc++.h>
    
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n;
        cin>>n;
        vector<string>a(n);
        int cnt[256]= {
        }
        ;
        for(string &s:a) {
            cin>>s;
            for(int j=0;j<(int)s.size();j+=2)cnt[stoi(s.substr(j,2),nullptr,16)]++;
        }
        vector<int>v(256);
        iota(v.begin(),v.end(),0);
        sort(v.begin(),v.end(),[&](int x,int y){return cnt[x]!=cnt[y]?cnt[x]>cnt[y]:x<y;});
        string hex="0123456789ABCDEF";
        for(int i=0;i<16;i++)cout<<hex[v[i]/16]<<hex[v[i]%16];
        cout<<"\n";
        for(string s:a) {
            for(int j=0;j<(int)s.size();j+=2) {
                int x=stoi(s.substr(j,2),nullptr,16),best=0;
                for(int k=1;k<16;k++)if(abs(x-v[k])<abs(x-v[best]))best=k;
                cout<<hex[best];
            }
            cout<<"\n";
        }
    }
    

    说明

    本题解为配套教学整理,非官方题解。复杂度按本页参考实现计算,题库使用12个自行生成的测试点。

    • 1

    信息

    ID
    698
    时间
    1000ms
    内存
    512MiB
    难度
    进阶
    标签
    递交数
    1
    已通过
    1
    上传者