#1572 小Hi與花盆

Time Limit:10000ms
Case Time Limit:1000ms
Memory Limit:256MB

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 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章