离散化思想的和它的两种代码

来源:互联网 发布:x战警天启知乎 编辑:程序博客网 时间:2024/06/03 20:25

     离散化代码的应用在我上一篇博客里有体现。

离散化思想:因为数字太大,导致没有办法开那么大的数组,又因为数字个数并不多,这时候就可以对它们进行离散化,离散化是改变了数字的相对大小,例如,有500000个数字,他们的范围是0-1e9的,这样就满足离散化的条件。

就比如说,你可以开一个5e5的数组,但是你不能开一个1e9的数组。只改变这些数字的相对大小


第一种离散化。

离散化以前一直搞不懂是怎么实现的,看了一个代码才明白。

const int maxn=1e5+10;

int a[maxn], t[maxn];

int n;

scanf("%d",&n);

for(int i=1;i<=n;i++)
            scanf("%d",a+i);

for(int i=1;i<=n;i++)
        t[i]=a[i];
    sort(t+1,t+n+1);
    m=unique(t+1,t+1+n)-t-1;

int pos=lower_bound(t+1,t+1+m,a[i])-t;

每个a[i]离散化后成了pos,可以开个数组存一下,也可以不存,每次都这样算就行;

用pos表示a[i]离散化后的数字,用t[pos]表示(pos)原来的数字;

举个栗子:

原序列:6 9 4 6 4

排序后:4 4 6 6 9

unique(元素去掉重复的)后:4 6 9 6 9  (前m位数字无重复,其他数字不改变)

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为不重复的数字的个数







  第二种离散化

struct A
{
    int x, idx;
    bool operator < (const A &rhs) const
    {
        return x < rhs.x;
    }
};

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]=2rank[2]=3,rank[3]=4;

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]是原来的数字;

rank是离散化后的数字;



两种方法会一种即可





原创粉丝点击