- GESP四级真题(202306):图像压缩
1
- @ 2026-7-31 15:26:39
#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 条评论
目前还没有评论...
信息
- ID
- 5756
- 时间
- ms
- 内存
- MiB
- 难度
- 8
- 标签
- 递交数
- 16
- 已通过
- 6
- 上传者