51nod1521(set.upper_bound())

题目链接: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 }




原文地址:https://www.cnblogs.com/geloutingyu/p/6308899.html