坐标离散化
坐标离散化是一种常见的技巧,对于一些数据量特别大的题目往往有奇效。
举个例子,你需要对输入的 n (n <= 1e5)个数进行标记,每个数标记一下(visit[i] = 1),但是如果对于每一个输入的数字 ai <= 1e18,我们就没办法去建立一个长度为1e18的数组,(当然可以用 set 或者 map),但是其实我们在存放这些数据的时候根本用不到那么大的数组,我们可以对数组的每一个数字编一个对应的编号(从1 到 n),通过编号可以查询到对应的值,通过值也可以获取编号,这样我们可以通过一个长度为 n 的数组去实现。
对于这样一个例子
1 5 8 4 7
根据每个数字的相对大小编号,就变成了下面的样子
1 3 5 2 4
方法其实很简单,首先输入数据,将数据保存在另一个数组中,对其中任一个数组排序 + 去重,通过对未排序的数组的每个值在已经排序的数组中二分查找位置,就可以得到该值在原序列中的相对大小,如果有重复的元素,那么他们的相对大小一定相同,我们把重复的元素去掉了,因此保证排完序的数组中每个值都是唯一的。
通过值可以用二分获取编号,通过编号可用已排序的数组获取值
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int a[1100];
int b[1100];
int c[1100];
int len;
int getid(int n){
return lower_bound(a + 1, a + len + 1, n) - a;
}
int main()
{
for (int i = 1; i <= 5; i++){
cin >> a[i];
b[i] = a[i];
}
sort(a + 1, a + 1 + 5);
len = unique(a + 1, a + 6) - a - 1;
for (int i = 1; i <= 5; i++){
c[i] = getid(b[i]);
}
for (int i = 1; i <= 5; i++)cout << c[i] << " ";
return 0;
}
本文来自博客园,作者:correct,转载请注明原文链接:https://www.cnblogs.com/correct/p/12862074.html

浙公网安备 33010602011771号