#include using namespace std; const int N = 256; //桶 int b[N];//0 ~ 255 //将一个16进制的灰阶转为一个整数,方便用来当数组的下标索引值 int toDec(char a, char b) { int res = 0; if (a >= 'A' && a <= 'F') res += (a - 'A' + 10) * 16; else res += (a - '0') * 16; if (b >= 'A' && b <= 'F') res += b - 'A' + 10; else res += b - '0'; return res; } //将一个十进制的灰阶值[0,255]转化成十六进制[0,FF] string toHex(int x) { int a = x % 16; // 0 ~ 15 int b = x / 16; // char c1; if (a >= 10) c1 = 'A' + a - 10; else c1 = '0' + a; char c2; if (b >= 10) c2 = 'A' + b - 10; else c2 = '0' + b; string res; res.push_back(c2); res.push_back(c1); return res; } //原始的字符串数组 vector q; //结构体,用来把桶中的灰阶按数量排序用的 struct Node { int id;//数组下标 int cnt;//个数 const bool operator<(const Node &b) const { if (cnt == b.cnt) return id < b.id; return cnt > b.cnt; } }; vector vec;//需要把b组装成Node放到数组p中,才能使用结构体排序吧 int main() { //将测试用例引入 freopen("D://HuiJie.txt", "r", stdin); //freopen("D://test.txt", "w",stdout); int n; cin >> n;//有n行数据组成了图像 for (int i = 1; i <= n; i++) { string s; cin >> s; q.push_back(s);//原始数组 for (int j = 0; j < s.size(); j += 2) { char c1 = s[j], c2 = s[j + 1]; int k = toDec(c1, c2); //灰阶对应的数组位置 b[k]++; } } //找出前16位使用频率高的灰阶 //排序,按什么排序呢? //1、按数量,数量多的在前 //2、如果数量一样多呢?桶中索引小的在前 for (int i = 0; i <= 255; i++) { if (b[i]) //数量大于0的才有意义 vec.push_back({i, b[i]}); } //使用自定义排序方法排序 sort(vec.begin(), vec.end()); //第一问 for (int i = 0; i < min(16, (int)vec.size()); i++) cout << toHex(vec[i].id); cout << endl; //第二问 for (int i = 0; i < n; i++) { //枚举每个原始字符串,每2个一组,判断这个小串应该与尺子数组中的哪一个更接近 for (int j = 0; j < q[0].size(); j += 2) {//长度是一样长的 char c1 = q[i][j], c2 = q[i][j + 1]; //计算ab组装出的短串与上面vec中的前16个哪个距离最短 int x = toDec(c1, c2); int mi = INT_MAX; int mi_p = 0; for (int k = 0; k < min(16, (int)vec.size()); k++) { //16是有风险的,因为可能没有16个那么多 if (mi > abs(vec[k].id - x)) { mi = abs(vec[k].id - x); mi_p = k; } } //mi_p [0,255] -> 十六进制 //将当前的a,b这个值修改为mi_p这个灰阶值 cout << toHex(mi_p)[1]; } cout << endl; } return 0; }