Description
小Hi家的陽臺上擺着一排N個空花盆,編號1~N。從第一天開始,小Hi每天會選擇其中一個還空着花盆,栽種一株月季花,直到N個花盆都栽種滿月季。
我們知道小Hi每天選擇的花盆的編號依次是A1, A2, ... AN。隨着花盆中被栽種上月季,連續的空花盆數量越來越少。
現在小Ho想知道,第一次出現恰好K個連續空花盆(恰好是指這K個空花盆兩邊相鄰的位置都不是空花盆)是第幾天?
假設N=7,K=2,小Hi第1天~第7天選擇的花盆編號依次是:4、2、7、5、1、3、6。
1234567 OOOOOOO 第0天,一段7個連續空花盆 OOOXOOO 第1天,一段3個連續空花盆,和另一段3連續個空花盆 OXOXOOO 第2天,1個、1個和3個連續空花盆 OXOXOOX 第3天,第一次出現2個連續空花盆 ....
Input
第一行包含兩個整數,N和K。
第二行包含N個兩兩不同的整數,A1, A2, ... AN。
對於30%的數據, 1 <= K < N <= 1000
對於100%的數據,1 <= K < N <= 100000, 1 <= Ai <= N
Output
輸出第一次出現恰好連續K個空花盆是第幾天。如果自始至終沒出現輸出-1。
- Sample Input
-
7 2 4 2 7 5 1 3 6
- Sample Output
-
3
思路:每次在一個空花盆種植,會將原先的一個連續空花盆分裂成兩個連續空花盆,所以每次選擇一個空花盆編號,只要計算這個空花盆編號及與其最近的兩個編號的連續空花盆數,將產生的兩個值與K進行比較。所以需要降低查找的複雜度,可以用set(會默認按照升序排列好)。
C++代碼:
1 #include <iostream> 2 #include <set> 3 using namespace std; 4 5 int main() { 6 int N, K, id; 7 cin >> N >> K; 8 set<int> st; 9 int ans = -1; 10 st.insert(0); st.insert(N + 1); 11 bool finded = false; 12 for (int i = 1; i <= N; ++i) { 13 scanf("%d", &id); 14 if (finded) continue; 15 auto it = st.upper_bound(id); 16 int right = *it, left = *(--it); 17 if ((id - 1 - left == K) || (right - 1 - id == K)) { 18 finded = true; 19 ans = i; 20 } 21 st.insert(id); 22 } 23 printf("%d\n", ans); 24 return 0; 25 }