ACM_离散化

版权声明:抱最大的希望,为最大的努力,做最坏的打算。 https://blog.csdn.net/qq_37748451/article/details/86569013

https://blog.csdn.net/xiangaccepted/article/details/73276826

离散化:

             一些数字,他们的范围很大(0-1e9),但是个数不算多(1-1e5),并且这些数本身的数字大小不重要,

重要的是这些数字之间的相对大小(比如说某个数字是这些数字中的第几小,而与这个数字本身大小没有关系,

要的是相对大小)  (6 8 9 4 离散化后即为2 3 4 1)

离散化思想:因为数字太大,导致没办法开那么大的数组,又因为数字个数并不多,这个时候就可以对他们进行

离散化,离散化是改变了数字的相对大小,例如,有500000个数字,他们范围是0-1e9  就满足了离散化的条件

第一种离散化

     (包含重复元素,并且相同元素离散化后也要相同,推荐使用下面代码)

const int maxn=1e5+10;
int a[maxn], t[maxn], b[maxn];
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++)
    scanf("%d",a[i]),t[i]=a[i];
sort(t+1,t+n+1);
m=unique(t+1,t+1+n)-t-1;//求出的m为不重复的元素的个数
for(int i=1; i<=n; i++)
    b[i]=lower_bound(t+1,t+1+m,a[i])-t;
//a[i]为原来的数组,b[i]为离散化后的数组

原来的a[i] 离散化后成了后来的a[i];

    离散化后 a[i] 的范围(1-m);   

举个栗子:

     原序列:6 9 4 6 4

     排序后:4 4 6 6 9

     unique(元素去重)后:4 6 9 6 9

unique有一个返回值,例如有十个有序的数列3 3 5 5 6 6 6 7 7 8,不重复的数字有五个,

使用unique去重之后数列变成了3 5 6 7 8 6 6 7 7 8,它只改变了前五个数字后边的不变,

返回值是 最后一个改变的数字的地址。

so:m=unique(t+1,t+1+n)-t-1;一般要减去首地址(t+1),m为不重复的数字的个数

第二种离散化

  (复杂度低,1.包含重复元素,并且相同元素离散化后不相同 2.不包含重复元素,并且不同元素离散化后不同,推荐使用)

struct A
{
    int x, idx;
    bool operator < (const A &rhs) const
    {
        return x < rhs.x;
    }//也可以写个cmp函数排序
};
A a[MAXN];
int rank[MAXN];
int n;
scanf("%d",&n);
for(int i = 1; i <= n; ++i)
{
    scanf("%d", &a[i].x);
    a[i].idx = i;
}
//for(int i=1; i<=n; i++)
//    printf("%d  %d\n",a[i].idx,a[i].x);
//printf("\n");
sort(a + 1, a + n + 1);
//for(int i=1; i<=n; i++)
//    printf("%d  %d\n",a[i].idx,a[i].x);
//printf("\n");
for(int i = 1; i <= n; ++i)
{
    rank[a[i].idx] = i;
//    printf("rank[%d] = %d\n",a[i].idx,i);
}

举个栗子:
i       1 2 3 4

x      6 8 9 4

idx   1 2 3 4

排序后:

i       1 2 3 4  //离散化后的数字

x      4 6 8 9  

idx   4 1 2 3  //数字原来的所在位置编号

rank[4]=1,rank[1]=2,rank[2]=3,rank[3]=4;//rank[i]=j 表示将原来在第i个位置上的数字离散化成j

so:
rank[1]=2;
rank[2]=3;
rank[3]=4;
rank[4]=1;
so:   6 8 9 4

就离散化为2,3,4,1
如果你想用原来的数字,就用排过序的结构体a[2]=6,a[3]=8,a[4]=9,a[1]=4; //a[i]=j表示排过序后现在的a数组里第i个数字的是j。j也就是第i小。
a[i]是原来的数字;
rank是离散化后的数字;

猜你喜欢

转载自blog.csdn.net/qq_37748451/article/details/86569013