修改陣列
時間限制: 1.0s 記憶體限制: 256.0mb 本題總分:20 分
【問題描述】
給定乙個長度為 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。
第二行包含 n 個整數 a1, a2, · · · , an 。
【輸出格式】
輸出 n 個整數,依次是最終的 a1, a2, · · · , an。
【評測用例規模與約定】【樣例輸入】
52 1 1 3 4
【樣例輸出】
2 1 3 4 5
對於 80% 的評測用例,1 ≤ n ≤ 10000。
對於所有評測用例,1 ≤ n ≤ 100000,1 ≤ ai ≤ 1000000。
解題思路
bool標記每次+1很容易就t了(如果有n個數,全都為n,那麼這是o(n^2/2)的複雜度,當n=1e5時就已經超時了)。這題可以巧妙地利用並查集。 我們初始化i的父親為i,然後依次遍歷輸入的陣列,使a[i] = getf(a[i]),再令f(a[i]) = f(a[i]+1)即可。
假如我們連續輸入1,2,1,第一次輸入1,a[1] = getf(1) = 1,更新f[1] = getf(a[1]+1) = 2; 第二次輸入 輸入2,a[2] = getf(2) =2,更新f[2] = getf(a[2]+1) = 3,第三次 再輸入1,a[3] = getf(1) = getf(2) = 3, 這時候a[3]便等於3了,而這種查的時間複雜度僅為o( logn)。 很巧妙 好好體會。
整體時間複雜度o(n*logn*logn)。
code
#include using namespace std;
const int maxn = 1e6+5;
int a[maxn],f[maxn];
int getf(int x)
int main()
for(int i=1;i<=n;i++)
return 0;
}
藍橋杯省賽 修改陣列(並查集)
給定乙個長度為n 的陣列a a1,a2,an 陣列中有可能有重複出現的整數。現在小明要按以下方法將其修改為沒有重複整數的陣列。小明會依次修改a2,a3,an。當修改ai 時,小明會檢查ai 是否在a1 ai 1 現過。如果出現過,則小明會給ai 加上1 如果新的ai 仍在之前出現過,小明會持續給ai...
藍橋杯 並查集
c國由n個小島組成,為了方便小島之間聯絡,c國在小島間建立了m座大橋,每座大橋連線兩座小島。兩個小島間可能存在多座橋連線。然而,由於海水沖刷,有一些大橋面臨著不能使用的危險。如果兩個小島間的所有大橋都不能使用,則這兩座小島就不能直接到達了。然而,只要這兩座小島的居民能通過其他的橋或者其他的小島互相到...
藍橋杯 國王的煩惱(並查集)
include include include includeusing namespace std const int maxn 1e5 5 int n,m,pre maxn struct node a maxn int find int x return r bool join int x,in...