藍橋杯省賽 修改數組(並查集)

題目描述

  給定一個長度爲N 的數組A = [A1, A2,…,AN],數組中有可能有重複出現的整數。
  現在小明要按以下方法將其修改爲沒有重複整數的數組。小明會依次修改A2,A3,…, AN。當修改Ai 時,小明會檢查Ai 是否在A1~ Ai-1 中出現過。如果出現過,則小明會給Ai 加上1 ;如果新的Ai 仍在之前出現過,小明會持續給Ai 加1 ,直到Ai 沒有在A1~Ai-1中出現過。當AN 也經過上述修改之後,顯然A數組中就沒有重複的整數了。
 現在給定初始的A 數組,請你計算出最終的A 數組。
輸入
第一行包含一個整數N(1<=N<=100000)
第二行包含N個整數A1,A2,…,AN(1<=Ai<=1000000)
輸出
輸出N個整數,依次是最終的A1,A2,…,AN
樣例輸入
5
2 1 1 3 4
樣例輸出
2 1 3 4 5


題解
  next [ ] 數組存儲該數字下一個該存放的位置。如果有衝突,那麼就把該數字變爲next[ ] 中的數字,然後更新該位置的信息即可。只有當next[i]=i 的時候。該位置才“空閒”,纔可以存放,否則原來的位置有數字了,就要把新的數字往後挪到 next[i] 指示的位置,而不是,一個一個挪,再判斷。

#include<bits/stdc++.h>
using namespace std;
 
int ans[200000];
int nnext[1000000];
 
int find(int i) {
    return nnext[i] == i ? i : nnext[i] = find(nnext[i]);
}
int main() {
    for (int i = 0; i < 1000000; i++)
        nnext[i] = i;
    int n, a;
    scanf("%d", &n);
 
    for (int i = 0; i < n; i++) {
        scanf("%d", &a);
        ans[i] = find(a);
        nnext[ans[i]] = ans[i] + 1;		//更新next[]
    }
 
    for (int i = 0; i < n; i++) {
        printf("%d ", ans[i]);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章