二分模板题

蒜头君建立了一家火车站台连锁店,要在一条铁路线的所有车站里,选择一部分车站开办连锁店,销售各种口味的大蒜。

铁路线上有 nn 个车站,假设这条铁路线是一条直线,其中每个站点的坐标为 x_1,x_2,\ldots,x_nx1​​,x2​​,,xn​​。

蒜头君一共要开办 mm 个连锁店,并且不希望连锁店离得太近,以使得整体的收益最大化。他希望他的连锁店之间的最近距离尽可能大,你能帮他算出这个最大的最近距离吗?

输入格式

第一行输入用空格分隔的两个整数 n,m(2 \leq n \leq 10^5, 2 \leq m \leq n)n,m(2n105​​,2mn),分别表示车站数量和连锁店数量。

接下来一共 nn 行,每行一个整数 x_i{0 \leq x_i \leq 10^9}xi​​0xi​​109​​,表示车站的坐标。

输出格式

输出一行整数,表示最大的最近距离。

样例 2 说明

一共有 44 种选择方案:

  1. 5 7 9 10:最近距离为 min(7-5,9-7,10-9)=1min(75,97,109)=1
  2. 5 7 9 28:最近距离为 min(7-5,9-7,28-9)=2min(75,97,289)=2
  3. 5 7 10 28:最近距离为 min(7-5,10-7,28-10)=2min(75,107,2810)=2
  4. 7 9 10 28:最近距离为 min(9-7,10-9,28-10)=1min(97,109,2810)=1

因此,最大的最近距离为 22。

样例输入1

6 3
1
3
5
2
7
9

样例输出1

4

样例输入2

5 4
5
7
10
28
9

样例输出2

2

#include<bits/stdc++.h>
using namespace std;
#define M 0x7fffffff
int a[1000000];
int n,m,i,j;
bool check(int mid)
{
    int sum=1;
    int f= a[0];
    for(i=1; i<n; i++)
    {
        if(a[i]-f>=mid)
        {
            sum++;
            f=a[i];
        }
    }
    if(sum>=m)
        return true;
    return
        false;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(i=0; i<n; i++)
    {
        scanf("%d",&a[i]);
    }
    sort(a,a+n);
    int l=0,r=a[n-1],mid,ans;
    while(l<r)
    {
        int mid = (l+r)>>1;
        if(check(mid))
        {
            l = mid + 1;
            ans = mid;
        }
        else
        {
            r = mid;
        }
    }
    cout<<ans<<endl;

}

 

 1 二分模板
 2 bool check(int mid)
 3 {
 4     //检查mid是否可行
 5 }
 6 //这个二分找出的是最大满足要求的解
 7 //如果要求最小的话,check取反就行了
 8 int binary_search()
 9 {
10     
11     int l=0,r=amax_ans;//ans为题意允许的最大答案
12     while(l<r)
13     {
14         int mid = (l+r)>>1;
15         if(check(mid))
16         {
17             l = mid + 1;
18             ans = mid;
19         }
20         else
21         {
22             r = mid;
23         }
24     }
25     cout<<ans<<endl;
26 }

 



posted @ 2017-04-26 20:13  zhang_upstar  阅读(341)  评论(0)    收藏  举报