C++编程问题,离散化排序求解

C++离散化问题
试了多次无法AC,请指教
【题目描述】
输入n,再输入n个数,输出这个n个数各自的名次,相同情况见样例
n <= 1000
每个数字<=max long long
【输入样例】
3
5 1 1
【输出样例 】
2 1 1

这道题需要进行离散化,将每个数转化为它在所有不同数中的名次。离散化的过程包括以下几步:

  1. 新建一个数组a,将输入的n个数全部复制到该数组中。
  2. 对a数组进行排序。
  3. 新建一个map,将排序后数组中每个不同的数存入map,对应的值为该数在排序后数组中的下标。
  4. 依次输出输入的n个数在map中对应的名次即可。

下面是C++的一个AC代码实现(建议自己进行代码实现!这里展示的是一种实现思路):
 


#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
const int maxn = 1010;
long long a[maxn], b[maxn];
map<long long, int> mp;
int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        b[i] = a[i];
    }
    sort(b, b+n);
    int cnt = -1;
    for (int i = 0; i < n; i++) {
        if(mp.count(b[i]) == 0) {
            mp[b[i]] = ++cnt;
        }
    }
    for (int i = 0; i < n; i++) {
        cout << mp[a[i]] + 1 << ' ';
    }
    return 0;
}

上述代码将每个数都输出为其实际名次+1的形式,因此输出结果可能与题目所要求的格式不同,但是可以简单的调整。

#include <iostream>
using namespace std;
long long arr[1001];
int rank1[1001];
int max(int n)
{
    int ma = arr[0];
    for (int i = 1; i < n; i++)
        if (ma > arr[i])
            ma = arr[i];
    return ma;
}
int min(int n)
{
    int mi = arr[0];
    for (int i = 1; i < n; i++)
        if (mi > arr[i]) 
            mi = arr[i]; 
    return mi;
}
int min(int l, int n)
{
    int mi = max(n);
    for (int i = 0; i < n; i++)
        if (arr[i] > l && mi > arr[i]) 
            mi = arr[i]; 
    return mi;
}
void sort(int n)
{
    int mi = min(n);
    int cnt;
    int ra = 0;
    while (1)
    {
        cnt = 0;
        for (int i = 0; i < n; i++)
        {
            if (arr[i] == mi)
            {
                cnt++;
                rank1[i] = ra;
            }
        }
        if (cnt + ra == n) break;
        mi = min(mi, n);
        ra += cnt;
    }
}
int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) 
        cin >> arr[i];
    sort(n);
    for (int i = 0; i < n; i++)
    {
        if (i == 0) 
            cout << rank1[0];
        else
            cout << " " << rank1[i];
    }
    return 0;
}

  • 以下回答由chatgpt基于相关博客总结生成:

    这里问题描述与参考资料似乎不太一致,不过按照描述来,离散化排序问题的解法与大数阶乘问题并不相似,下面给出离散化排序问题的解法。

    首先,离散化的实现方法有很多,笔者列举两种方法:

    (1) 手写离散化:定义map或vector来映射原始数据到离散化后的数据,在排序时按照离散化后的数据进行操作。

    //手写离散化 //map实现 maph; int num[N],a[N],n=0; //数组num存放去重后的数据,n为去重后的数据个数 void init(){ for(int i=1;i<=n;i++) a[i]=num[i]; sort(a+1,a+1+n); int k=1; for(int i=1;i<=n;i++){ if(a[i]!=a[i-1]) h[a[i]]=k++; } } ... //排序 for(int i=1;i<=n;i++)b[i]=h[a[i]]; sort(b+1,b+1+n);

    (2) 通过STL库函数实现排序:

    //STL库函数实现离散化 //vector实现 vectorv; //存储原始数据 vectorres; //存储排序结果 ... //排序 res=v; sort(res.begin(),res.end()); res.erase(unique(res.begin(),res.end()),res.end()); for(int i=0;i<v.size();i++) printf("%d ",lower_bound(res.begin(),res.end(),v[i])-res.begin()+1);

    其次,在排序完成后,根据原始数据出现的顺序,遍历排序数组并将每个元素离散化后的结果输出即可,详见以下代码: