#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 }

 

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