山头狙击战

题目描述

Lucky为了掩护大部队,单枪匹马同敌人周旋,后来被敌人包围在某山头......,不过不用怕,Lucky携带了足够的弹药,完全可以将涌上来的敌人一个一个干掉。Lucky是个神枪手,只要他的枪膛中有子弹,他就能将在他射程m(用从敌人位置到山头的直线距离算)以内的一个敌人瞬间射杀,如果在射程内没有敌人,Lucky会等待敌人靠近然后射击。但他发现了一个致命的失误:他携带的枪是单发枪,每射出一发子弹都必须花k秒钟的时间装子弹。而凶残的敌人才不会花时间等你换子弹呢。他们始终在以1m/s的速度接近山头。而如果在一个敌人到达山头时Lucky无法将他击毙,那么我们可怜的Lucky就将牺牲在敌人的刺刀下。现在Lucky向你求助:要保住自己的性命并且歼灭所有敌人,Lucky最多只能用多少时间给枪装上一发子弹?

说明:假设一开始Lucky的枪中就有一发子弹,并且一旦确定一个装弹时间,Lucky始终会用这个时间完成子弹的装卸。希望你能帮助Lucky脱离险境。

输入输出格式

输入格式:

第一行,两个整数n和m(2≤n≤100000;1≤m≤10000000),n代表敌人个数,m代表Lucky的射程。

接下来有n行,每行一个整数mi(1≤mi≤10000000),代表每个敌人一开始相对山头的距离(单位为米)。

输出格式:

一行,仅有一个整数,代表Lucky的换弹时间(单位为秒)。

输入输出样例

输入样例:
6 100
236
120
120
120
120
120
输出样例:
25

(这题要用二分答案)
#include
using namespace std;
int n,m; 
int box1,box2;
int y[10000000];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&y[i]);
    }
    sort(y+1,y+1+n);//排序敌人和我的距离
    int l=1,r=10000000;
    while(l<r)
    {
        int mid=(l+r)/2;
        box1=0,box2=1;//计数器清0,归1 
        for(int i=1;i<=n;i++)
        {
            if(box1>y[i])
            {
                box2=0;
                break;
            }
            if(box1//如果换弹时间小于敌人离你的距离在射程范围内 
            {
                box1=y[i]-m; 
            }
            box1+=mid;
        }    
        if(box2==1) l=mid+1;//如果敌人死了说明可以缩短时间 
        else r=mid;    //否则杀不死就要延长
    }
    cout<1;
    return 0;
} 

 

转载于:https://www.cnblogs.com/liaoshuangqi/p/10551722.html

你可能感兴趣的:(山头狙击战)