CF One-Dimensional Battle Ships(set运用)

题目链接

                                                           One-Dimensional Battle Ships

                                    time limit per test 1 second memory limit per test 256 megabytes

Alice and Bob love playing one-dimensional battle ships. They play on the field in the form of a line consisting ofn square cells (that is, on a1 × n table).

At the beginning of the game Alice puts k ships on the field without telling their positions to Bob. Each ship looks as a 1 × a rectangle (that is, it occupies a sequence ofa consecutive squares of the field). The ships cannot intersect and even touch each other.

After that Bob makes a sequence of "shots". He names cells of the field and Alice either says that the cell is empty ("miss"), or that the cell belongs to some ship ("hit").

But here's the problem! Alice like to cheat. May be that is why she responds to each Bob's move with a "miss".

Help Bob catch Alice cheating — find Bob's first move, such that after it you can be sure that Alice cheated.

Input

The first line of the input contains three integers:n,k anda (1 ≤ n, k, a ≤ 2·105) — the size of the field, the number of the ships and the size of each ship. It is guaranteed that then,k anda are such that you can putk ships of sizea on the field, so that no two ships intersect or touch each other.

The second line contains integer m (1 ≤ m ≤ n) — the number of Bob's moves.

The third line contains m distinct integersx1, x2, ..., xm, where xi is the number of the cell where Bob made thei-th shot. The cells are numbered from left to right from1 ton.

Output

Print a single integer — the number of such Bob's first move, after which you can be sure that Alice lied. Bob's moves are numbered from1 tom in the order the were made. If the sought move doesn't exist, then print "-1".

Sample test(s)
Input
11 3 3
5
4 8 6 1 11
Output
3
Input
5 1 3
2
1 5
Output
-1
Input
5 1 3
1
3
Output
1
题目形象化:射靶子游戏,本渣前方有一个长度为n宽为1的长方形桌子,现在有k快长度为a宽为1的方块放在这个桌子上,放置方法就是任意两块方块不能相交而且不能相邻,而且本渣不知道具体放的位置,现在本渣蒙眼射击,虽然蒙眼,但是我想射哪里就射哪里,对于我每次射击的坐标(1~n),我的朋友都会告诉我是否射到方块,要么miss,要么hit,但是我的朋友很是调皮,他会撒谎,如果我hit了,他也会说miss,卧槽,雅蠛蝶呀,但是本渣还是有测谎能力的,现在给你我m次射击的位置(1~n),问你我能在第一次射击测出我的朋友在撒谎,如果始终不能测出来,那么输出-1。
输入第一行为n,k,a,代表意义如上述。
第二行为一个数m,代表射击次数。
第三行有m个数,代表每次射击的位置。
分析:对于每次射击,如果当前为miss,那么可以知道不会有方块在这个坐标,那么我们便可以算出剩下的长度最多能放多少这样的方块,如果算出的结果小于了k,那么说明这次射击我的朋友撒谎了,具体用set加二分查找维护即可。
#include<stdio.h>
#include<string.h>
#include<set>
#include<algorithm>
using namespace std;
int b[200002];///记录射击位置
int n,k,a;
int get(int L)//计算长度为L的桌子最多能放多少个1*a的方块
{
    if(L<a) return 0;
    return (L+1)/(a+1);
}
int main()
{
    scanf("%d%d%d",&n,&k,&a);
    int m;
    scanf("%d",&m);
    for(int i=1;i<=m;i++) scanf("%d",&b[i]);
    int sum=get(n);
    set<int> s;
    s.insert(0);
    s.insert(n+1);
    set<int>::iterator it;
    int flog=0;
    for(int i=1;i<=m;i++)
    {
        it=s.lower_bound(b[i]);
        int posy=*it;//存的是右边离此次射击最近的点
        it--;
        int posx=*it;//左边最近的点
        int x,y,l;
        y=posy-b[i]-1;
        x=b[i]-posx-1;
        l=posy-posx-1;//l为射击之间周围两个点的长度
        sum-=get(l);
        sum+=get(x)+get(y);
        s.insert(b[i]);
        if(sum<k)
        {
            flog=1;
            printf("%d\n",i);
            break;
        }
    }
    if(flog==0) puts("-1");
    return 0;
}

你可能感兴趣的:(set)