C++离散化问题
试了多次无法AC,请指教
【题目描述】
输入n,再输入n个数,输出这个n个数各自的名次,相同情况见样例
n <= 1000
每个数字<=max long long
【输入样例】
3
5 1 1
【输出样例 】
2 1 1
这道题需要进行离散化,将每个数转化为它在所有不同数中的名次。离散化的过程包括以下几步:
下面是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;
}
这里问题描述与参考资料似乎不太一致,不过按照描述来,离散化排序问题的解法与大数阶乘问题并不相似,下面给出离散化排序问题的解法。
首先,离散化的实现方法有很多,笔者列举两种方法:
(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);
其次,在排序完成后,根据原始数据出现的顺序,遍历排序数组并将每个元素离散化后的结果输出即可,详见以下代码: