2017年ACM模板(常用)弱渣整理 二、二分
阿新 • • 發佈:2019-01-23
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相比較來縮小範圍。