蓝桥杯省赛 修改数组(并查集)

题目描述

  给定一个长度为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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章