#include<bits/stdc++.h>
using namespace std;
int n;
struct node{
int cnt,num;
string color;
}a[256];
string s[25];
int change(char c){//字符0~F转成数值0~15
if(c<='9') return c-'0';
return c-'A'+10;
}
bool cmp(node a,node b){
if(a.cnt!=b.cnt)
return a.cnt>b.cnt;//按照出现次数从大到小排
else
return a.num<b.num;//如果出现次数一样,按照颜色大小从小到大排
}
int main()
{
cin>>n;
for(int i=0;i<n;i++) cin>>s[i];
int len=s[0].size();
//统计256种颜色出现的次数,即00~FF
for(int i=0;i<n;i++){
//一个像素由十六进制两个字符构成
for(int j=0;j<len;j+=2)
{
string t=s[i].substr(j,2);//t就是一个像素点
//将十六进制的像素点转换为十进制的数
int num=change(t[0])*16+change(t[1])*1;
if(a[num].cnt==0)//像素中的颜色第一次出现
a[num]={1,num,t};
else
a[num].cnt++;
}
}
sort(a,a+256,cmp); //sort如果没有cmp那么会按照从小到大的顺序排序
//输出前16种颜色
for(int i=0;i<16;i++)
cout<<a[i].color;
cout<<endl;
for(int i=0;i<n;i++,puts(""))
//一个像素由十六进制两个字符构成
for(int j=0;j<len;j+=2) {
//将十六进制的像素点转换为十进制的数
int num=change(s[i][j])*16+change(s[i][j+1])*1;
int minn=INT_MAX,idx;//minn记录当前像素点的颜色和表格中16个颜色的差值
//idx记录最小差值在表格中下标
for(int k=0;k<16;k++){
if(abs(a[k].num-num)<minn){
minn= abs(a[k].num-num);
idx=k;
}
}
//将0~15转换成0~F
if(idx<10) cout<<idx;
else cout<<char('A'+idx-10);
}
return 0;
}
解题思路:
1.遍历图片中的每个像素点,统计每个颜色出现的次数。
2.排序后,输出出现次数最多的16种颜色。
3.重新遍历每一个像素点,对照第二步中排序好的颜色,输出距离每个像素点最近的颜色的下标。