51Nod 1521

51Nod 1521
中文题,题意不说了。
思路:先看初始区间能装多少战舰,如果能就把初始范围0~(n+1)放入set中,然后依次把判断的点加入set,每加入一个,用lower_bound找出左右区间,ans-老区间能装多少个+新的两个区间能装多少个。set用lower_bound要这样用s.lower_bound(b[i]),用lower_bound(s.begin(),s.end(),b[i])用超时。


#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f3f3f3f3f
const int maxn=2e5+10;
#define mem(aa,bb) memset(aa,bb,sizeof(aa))
#define PI acos(-1.0)
int n,k,a;
set<int>s;
int b[maxn];
int main()
{
    while(~scanf("%d%d%d",&n,&k,&a))
    {
        s.clear();
        int q;
        scanf("%d",&q);
        for(int i=1; i<=q; i++)
        {
            scanf("%d",&b[i]);
        }
        int ans=0;
        int len=(n);
        int a1=len/(a+1);
        int a2=len%(a+1)==a?1:0;
        ans+=(a1+a2);
        //printf("      %d\n",ans);printf("len= %d %d\n",,a2);
        if(ans<k)
        {
            printf("1\n");
            continue;
        }
        s.insert(0);
        s.insert(n+1);
        int flag=0;
        for(int i=1; i<=q; i++)
        {
            //set<int>::iterator it;
            set<int>::iterator it=s.lower_bound(b[i]);
            set<int>::iterator it1,it2,itt;
            itt=it;
            if(*it==(n+1))
                it2=itt;
            else
                it2=itt++;
            it1=--it;
            it++;
            //printf("   %d %d\n",*it1,*it2);
            len=*it2-*it1-1;
            a1=len/(a+1);
            a2=len%(a+1)==a?1:0;
            ans-=(a1+a2);

            s.insert(b[i]);
            it=s.lower_bound(b[i]);
            len=*it-*it1-1;
            a1=len/(a+1);
            a2=len%(a+1)==a?1:0;
            ans+=(a1+a2);
            //printf("ans=%d\n",ans);
            len=*it2-*it-1;
            a1=len/(a+1);
            a2=len%(a+1)==a?1:0;
            ans+=(a1+a2);
            //printf("ans=%d\n",ans);
            if(ans<k)
            {
                printf("%d\n",i);
                flag=1;
                break;
            }
        }
        if(!flag)
            printf("-1\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值