0x04 二分
Posted kkkstra
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了0x04 二分相关的知识,希望对你有一定的参考价值。
整数集合上的二分:
while (l<r) int mid=(l+r)>>1; if (check(mid)) r=mid; else l=mid+1;
或者
while (l<r) int mid=(l+r+1)>>1; if (check(mid)) l=mid; else r=mid-1;
注意事项:
1.(l+r)/2是向0取整,(l+r)>>1则是向下取整
2.注意(l+r)>>1与(l+r+1)>>1的区别
实数域上的二分:
直接定义一个精度值eps即可
double eps=1e-5; while (l+eps<r) double mid=(l+r)/2; if (check(mid)) r=mid; else l=mid;
有时精度不容易确定,直接设定循环次数即可,精度会较前一种更高
for (int i=1; i<=100; ++i) double mid=(l+r)/2; if (check(mid)) r=mid; else l=mid;
二分答案,判定即可
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 using namespace std; 7 const int maxn=100000+10; 8 int n, L; 9 double a[maxn], b[maxn], sum[maxn]; 10 11 int main() 12 scanf("%d%d", &n, &L); 13 for (int i=1; i<=n; ++i) 14 scanf("%lf", &a[i]); 15 double eps=1e-5; 16 double l=-1e6, r=1e6; 17 while (r-l>eps) 18 double mid=(l+r)/2; 19 for (int i=1; i<=n; ++i) 20 b[i]=a[i]-mid; 21 for (int i=1; i<=n; ++i) 22 sum[i]=sum[i-1]+b[i]; 23 double minv=1e10, ans=-1e10; 24 for (int i=L; i<=n; ++i) 25 minv=min(minv, sum[i-L]); 26 ans=max(ans, sum[i]-minv); 27 28 if (ans>=0) l=mid; //平均数可以达到 29 else r=mid; 30 31 printf("%d\n", int(r*1000)); 32 return 0; 33
以上是关于0x04 二分的主要内容,如果未能解决你的问题,请参考以下文章