1. 程式人生 > >2017年ACM模板(常用)弱渣整理 二、二分

2017年ACM模板(常用)弱渣整理 二、二分

lower_bound

lower_bound 這個函式是從已經排好序的序列a中利用二分搜尋找出指向滿足ai >= k的ai的最小的指標,注意是指標。upper_bound函式類似,就是求出滿足ai > k的ai的最小的指標。

#include<cstdio>
#include<algorithm>
using namespace std;
int a[100];
int main()
{
    printf("輸入序列個數:\n");
    int k;
    scanf("%d",&k);
    printf("輸入序列:\n"); 
    for
(int i=0; i<k; i++) { scanf("%d",&a[i]); } sort(a, a+k); printf("輸入查詢的數:\n"); int t; scanf("%d",&t); printf("lower_bound:%d\n",lower_bound(a, a+k, t)-a); printf("upper_bound:%d\n",upper_bound(a, a+k, t)-a); return 0; }

因為lower_bound函式是查詢 ai >= k 的最小的指標。
而upper_bound函式是查詢ai > k的最小的指標,那麼就可以通過這個差異求出序列a中k的個數:
upper_bound(a, a+n, k) - lower_bound(a, a+n, k)

問題一、最大化最小值

M為放置的個數

bool C(int d)
{
    int last = 0;
    for(int i=1; i<M; i++)
    {
        int crt = last + 1;
        while(crt<N && x[crt] - x[last] < d)
        {
            crt++;
        }
        if(crt == N) return false; 
        last = crt; 
    }
    return true;
}

問題二、最大化平均值

bool C(double d)
{
    for(int i=0; i<n; i++)
    {
        y[i] = v[i] - d * w[i];
    }
    sort(y, y+n);

    double sum = 0;
    for(int i=0; i<k; i++)
    {
        sum += y[n-i-1];
    }
    return sum >= 0;
}

問題三、尋找第k大值

bool C(int d)
{
    int cnt = 0;
    for(int i=0; i<N; i++)
    {
        cnt += (upper_bound(a+i, a+N, a[i]+d)-1 - (a+i));   
    }
    if(cnt >= M) return true;
    else return false;
}

類似這種二分套二分的思想,二分第k大的值統計<=k的個數,與k相比較來縮小範圍。