H题题解

本题为模拟题,注意题目要求并且按照规则输出即可 首先统计每两个字符(即该十六进制数)出现的次数 其次按照出现次数从大到小、相同的灰阶值从小到大的顺序排序排序,最后选出前十六个在第一行输出 最后对于原先的灰阶值一一对应输出它所对应的编号,如果不在第一行的十六个数中,那么就要选择“最近”的灰阶值,因为数据很小,最多只需十六次可以直接暴力枚举找到最小值,(也可以用二分找到最小值,不过这里没必要

#include <bits/stdc++.h>
using namespace std;
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//#define int long long
typedef vector<vector<int>> mat;
using pii = pair<int, int>;
using pdd = pair<double,double>;
constexpr int N = 2e5 + 10;
void solve()
{
    int n;
    cin>>n;
    vector<string> s(n+10);
    map<int ,int> mp,id;
    for(int i=1;i<=n;i++) cin>>s[i];
    int len=s[1].size();
    for(int k=1;k<=n;k++)
    {
        for(int i=0;i<len;i+=2)
        {
            string str="";
            str+=s[k][i];
            str+=s[k][i+1];
            mp[stoi(str,nullptr,16)]++;//stoi字符串转换成int转换成十六进制
        }
    }
    vector<pii> v;
    for(auto &[x,y]:mp) v.push_back({x,y});
    sort(v.begin(),v.end(),[](auto &a,auto &b)
    {
        if(a.second!=b.second) return a.second>b.second;//降序
        return a.first<b.first;//升序
    });
    for(int i=0;i<16;i++)
    {
        printf("%02X",v[i].first);
        id[v[i].first]=i;
    }
    cout<<'\n';
    for(int k=1;k<=n;k++)
    {
        for(int i=0;i<len;i+=2)
        {
            string str="";
            str+=s[k][i];
            str+=s[k][i+1];
            int vl=stoi(str,nullptr,16);
            int ans_id,mi=1e9;
            for(int j=0;j<16;j++)
            {
                int d=abs(vl-v[j].first);//
                if(d<mi)
                {
                    mi=d;
                    ans_id=j;
                }
                else if(d==mi&&j<ans_id) ans_id=j;
            }
            printf("%X",ans_id);
        }
        cout<<'\n';
    }
    
}
signed main()
{
    int _= 1;
    //cin >> _;
    while(_--)
    {
        solve();
    }
    return 0;
}

0 条评论

目前还没有评论...