離散化思想

2021-08-25 08:41:46 字數 3047 閱讀 1446

離散化是什麼:一些數,他們的範圍很大(0-1e9),但是個數不算多(1-1e5),並且這些數本身的數大小不重要,重要的是這些數之間的相對大小(比如說某個數是這些數中的第幾小,而與這個數本身大小沒有關係,要的是相對大小)(6 8 9 4 離散化後即為2 3 4 1)(要理解相對大小的意思)(6在這4個數中排第二小,那麼就把6離散化成2,與數6本身沒有關係, 8,9,4亦是如此)(2018.3.26 對這篇部落格進行補充修改,被一道題的離散化卡到了,花了一晚上時間,才找到bug(需離散化的數有無相同的數),黑體為今晚對此篇部落格進行了補充完善與區別)

離散化思想:因為數字太大,導致沒有辦法開那麼大的陣列,又因為數字個數並不多,這時候就可以對它們進行離散化,離散化是改變了數字的相對大小,例如,有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]),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++)

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

原來的a[i]離散化後成了後來的a[i];

離散化後的a[i]範圍是(1-m);

舉個栗子:

原序列:6 9 4 6 4

排序後:4 4 6 6 9

unique(元素去掉重複的)後:4 6 9 6 9( 感謝薇亞040214同學提出疑問,為什麼unique去重後是4,6,9,6,9,而不是4,6,9,4,9,大家執行下面的**即可,2018.7.21更)

(siriusneo大佬的解答:unique去重完後面的元素是不變的,所以是4 6 9 6 9,具體可以看c++ reference的原始碼

2018.8.6更)

#include #include using namespace std;

int a[10]=;

int main()

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.不包含重複元素,並且不同元素離散化後不同,符合這兩種的其中乙個,推薦使用  |   感謝angel-yan同學指出錯誤,2018.7.21更正)

struct a

//也可以寫個cmp函式排序

};a a[maxn];

int rank[maxn];

int n;

scanf("%d",&n);

for(int i = 1; i <= n; ++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)

給你們個例子:

i      1 2 3 4

x     6 8 9 4

idx  1 2 3 4

排序後:

i1 2 3 4  //離散化後的數

x     4 6 8 9 

idx4 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是離散化後的數字;

離散化思想

離散化,把無限空間中有限的個體對映到有限的空間中去,以此提高演算法的時空效率。通俗的說,離散化是在不改變資料相對大小的條件下,對資料進行相應的縮小。例如 原資料 1,999,100000,15 處理後 1,3,4,2 原資料 處理後 include include include using nam...

離散化思想

最近做了一些需要離散資料的題目,比如ural 1019 以及poj 2528等,由於資料較大,如果用傳統的方法建立對應的資料結構消耗的記憶體和時間肯定是不能被接受的。由於以前沒有怎麼接觸過需要離散化的題目,於是就通過自己最近的做題經驗以及網上的部分資料,整理並講解了常用的離散資料的方法。何為離散化?...

離散化思想

離散化是程式設計中乙個非常常用的技巧,它可以有效的降低時間複雜度。其基本思想就是在眾多可能的情況中 只考慮我需要用的值 下面我將用三個例子說明,如何運用離散化改進乙個低效的,甚至根本不可能實現的演算法。演算法藝術與資訊學競賽 中的計算幾何部分,黃亮舉了乙個經典的例子,我認為很適合用來介紹離散化思想。...