#include<bits/stdc++.h>
using namespace std;

// 将两位十六进制字符串转为十进制值(0~255)
int z10(string x){
    int ans=0;
    if(x[0]>='0'&&x[0]<='9') ans+=(x[0]-'0')*16;
    else ans+=(x[0]-'A'+10)*16;
    if(x[1]>='0'&&x[1]<='9') ans+=(x[1]-'0');
    else ans+=(x[1]-'A'+10);    
    return ans;
}

// 将十进制值转为两位十六进制字符串(自动补零)
string z16(int x){
    string ans="";
    while(x){
        if(x%16>9){
            ans=char((x%16)-10+'A')+ans;
        }
        else{
            ans=char((x%16)+'0')+ans;
        }
        x/=16;
    }
    if(ans.size()==1) ans="0"+ans;
    else if(ans.size()==0) ans="00"+ans;
    return ans; 
} 

int t[256];          // 统计每种灰阶出现次数
struct num{
    int id, sum;     // id:灰阶值,sum:出现次数
}d[300];

bool cmp(num x, num y){
    if(x.sum != y.sum) return x.sum > y.sum; // 次数多的优先
    else return x.id < y.id;                 // 次数相同,值小的优先
}

// 将编号(0~15)转为单个十六进制字符
char toHex(int v){
    if(v < 10) return '0' + v;
    else return 'A' + (v - 10);
}

int main(){
    int n;
    cin >> n;                // 行数
    vector<int> pixels;      // 存储所有像素的十进制值

    char a, b;
    // 读取所有像素(每两个字符为一个像素)
    while(cin >> a >> b){
        string x = "";
        x.push_back(a);
        x.push_back(b);
        int val = z10(x);
        t[val]++;            // 统计
        pixels.push_back(val);
    }

    // 初始化结构体数组
    for(int i = 0; i < 256; i++){
        d[i].id = i;
        d[i].sum = t[i];
    }

    // 按出现次数降序,次数相同按灰阶值升序排序
    sort(d, d + 256, cmp);

    // 输出第一行:选定的16种灰阶,按编号0~F顺序
    for(int i = 0; i < 16; i++){
        cout << z16(d[i].id);
    }
    cout << endl;

    // 计算每行像素个数(所有行等长)
    int rowLen = pixels.size() / n;

    // 输出压缩后的图像
    for(int i = 0; i < (int)pixels.size(); i++){
        int val = pixels[i];
        int bestIdx = 0;                     // 最佳编号
        int bestDist = abs(val - d[0].id);   // 到第0个选定灰阶的距离

        // 遍历选定的16种灰阶,找最近
        for(int j = 1; j < 16; j++){
            int dist = abs(val - d[j].id);
            if(dist < bestDist || (dist == bestDist && j < bestIdx)){
                bestDist = dist;
                bestIdx = j;
            }
        }

        cout << toHex(bestIdx);

        // 每行末尾换行
        if((i + 1) % rowLen == 0){
            cout << endl;
        }
    }

    return 0;
}

0 条评论

目前还没有评论...

GESP四级真题(202306):图像压缩

信息

ID
5756
时间
ms
内存
MiB
难度
8
标签
递交数
16
已通过
6
上传者