有n頭奶牛,已知它們的身高為 1~n 且各不相同,但不知道每頭奶牛的具體身高。
現在這n頭奶牛站成一列,已知第i頭牛前面有ai
頭牛比它低,求每頭奶牛的身高。
輸入格式
第1行:輸入整數n。
第2…n行:每行輸入乙個整數ai
,第i行表示第i頭牛前面有ai
頭牛比它低。
(注意:因為第1頭牛前面沒有牛,所以並沒有將它列出)
輸出格式
輸出包含n行,每行輸出乙個整數表示牛的身高。
第i行輸出第i頭牛的身高。
資料範圍
1≤n≤105
輸入樣例:51
210輸出樣例:24
531分析:
在分析的時候,明確自己需要啥。然後,在不斷模擬的過程中,找到更簡便的方法,達到自己的目的。
這個題,我一波錯誤分析,wa飛了。xuxuxu
看到題目。很自然而然的相到從後面往前找。因為最後乙個的身高一定為
h[n] = a[n] + 1.
那麼前乙個的身高為多少呢?
h[n-1] = a[n-1] + 1 (if(a[n -1] < a[n]) 或者
h[n-1] = a[n-1] + 2 (if ( a[n -1] >= a[n])
這是容易得到的。
所以,我們
對於每個h[i] = a[i] + 1 + x.我就是因為這裡想錯了。我一開始想的是對於每個a[i]求一下他之前出現的個數有多少個。但是後面發現這並不行。
其實,我們由h[n-1]可以得到另外乙個思想:
對於每個h[i] 是不是在(1-n)這個序列(這個序列不包括已經安排了的身高)中找到第a[i] + 1大的那個數就好了呢。
故,我們的目的現在變成了,對於每個h[i] 在序列(1-n)中找到未出現過的身高的第a[i]+1大的值就可以了。
為了達到這個目的,通俗的想便是遍歷一次序列找到那個值。但是這樣很明顯超時。
那麼我們用乙個c陣列。c[i] 表示前i個數有多少個數是未被使用過的,這樣是可以的。
然後,我們便可以用二分或者倍增的方法求出第a[i] + 1大的那個數了。
如果i這個數被使用了,則要修改c陣列。這不就是樹狀陣列的單點修改嗎。
明確目的,通過方法解決目的。開展思維,證明可行性。
#include"stdio.h"
#include"string.h"
#include"algorithm"
using namespace std;
int n,a[100100];
int c[100010];
int h[100010];
int id[100010];
int s;
int lowbit(int x)
void add(int x,int v)
}int ask(int x)
return sum;
}int main()
for(int i = n; i >= 2; i --)
h[i] = l;
add(l,-1);
s -= l;
}h[1] = s;
for(int i = 1; i <= n; i ++)
printf("%d\n",h[i]);
}
謎一樣的牛 樹狀陣列
有n頭奶牛,已知它們的身高為 1 n 且各不相同,但不知道每頭奶牛的具體身高。現在這n頭奶牛站成一列,已知第i頭牛前面有ai頭牛比它低,求每頭奶牛的身高。輸入格式 第1行 輸入整數n。第2 n行 每行輸入乙個整數ai,第i行表示第i頭牛前面有ai頭牛比它低。注意 因為第1頭牛前面沒有牛,所以並沒有將...
謎一樣的牛 樹狀陣列
有n頭奶牛,已知它們的身高為 1 n 且各不相同,但不知道每頭奶牛的具體身高。現在這n頭奶牛站成一列,已知第i頭牛前面有ai頭牛比它低,求每頭奶牛的身高。輸入格式 第1行 輸入整數n。第2 n行 每行輸入乙個整數ai,第i行表示第i頭牛前面有ai頭牛比它低。注意 因為第1頭牛前面沒有牛,所以並沒有將...
ACwing 244 謎一樣的牛
時 空限制 1s 64mb 有n頭奶牛,已知它們的身高為 1 n 且各不相同,但不知道每頭奶牛的具體身高。現在這n頭奶牛站成一列,已知第i頭牛前面有aiai頭牛比它低,求每頭奶牛的身高。輸入格式 第1行 輸入整數n。第2.n行 每行輸入乙個整數aiai,第i行表示第i頭牛前面有aiai頭牛比它低。注...