题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1521
题意:中文题诶~
思路:
我们先看一下set容器的三个库函数:
iterator lower_bound (const value_type& val) const;
iterator upper_bound (const value_type& val) const;
pair<iterator,iterator> equal_range (const value_type& val) const;
前两者和一般的lower_bound()/upper_bound()函数差不多;
equal_range返回两个迭代器,第一个迭代器是set.lower_bound的返回值,第二个迭代器是set.upper_bound的返回值
(注意是使用相同val值调用的情况下。)
对于连续s个可以放置战舰的空格,假设其最多可以放置x艘战舰,那么有:x*a+(x-1)<=s, 解得: x<=(s+1)/(size+1);
我们先声明一个set变量st, 里面存储不能放置战舰的空格.
对于每一次询问的位置x,其都会将一段连续可以放置战舰的空间分成两段;假设我们用gg变量存储当前最多可以放置的战舰的数目,
那么我们询问一次后将gg更新为:gg=gg-被分成两段的空间原本最多可以放的战舰数目+被拆成两段后最多可以放置的战舰数目;
若更新后gg小于战舰数目,那么我们可以确定爱丽丝说谎了;
代码:
1 #include <bits/stdc++.h>
2 using namespace std;
3
4 int main(void){
5 set<int> st;
6 int n, k, size, x, gg=0, pos=0, t;
7 bool flag=true;
8 set<int>::iterator it;
9 scanf("%d%d%d", &n, &k, &size);
10 gg=(n+1)/(size+1);
11 st.insert(n+1); //***一开始第n+1个空格坑定不能放战舰啦
12 cin >> t;
13 for(int i=1; i<=t; i++){
14 scanf("%d", &x);
15 if(flag){
16 it=st.upper_bound(x);
17 int cnt=*it;
18 if(it==st.begin()){
19 gg=gg-cnt/(size+1)+x/(size+1)+(cnt-x)/(size+1);
20 }else{
21 it--;
22 int num=*it;
23 gg=gg-(cnt-num)/(size+1)+(x-num)/(size+1)+(cnt-x)/(size+1);
24 }
25 if(gg<k){
26 pos=i;
27 flag=false;
28 }else{
29 st.insert(x);
30 }
31 }
32 }
33 if(flag){
34 cout << -1 << endl;
35 }else{
36 cout << pos << endl;
37 }
38 }