『一本通』二分与三分

Posted qq8260573

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了『一本通』二分与三分相关的知识,希望对你有一定的参考价值。

愤怒的牛

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,ans,a[100005];
 4 
 5 int check(int x) {
 6     int cnt=1,lst=a[1];
 7     for(int i=2;i<=n;i++)
 8      if(a[i]-lst>=x) cnt++,lst=a[i];
 9     return cnt;
10 }
11 
12 int main() {
13     scanf("%d%d",&n,&m);
14     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
15     sort(a+1,a+n+1);
16     int l=1,r=a[n]-a[1];
17     while(l<=r) {
18         int Mid=l+r>>1;
19         if(check(Mid)>=m) l=Mid+1,ans=Mid;
20         else r=Mid-1;
21     }
22     printf("%d",ans);
23 }

 

Best Cow Fences

 1 #include<bits/stdc++.h>
 2 #define N 100005
 3 using namespace std;
 4 int n,L,ans,a[N];
 5 long long s[N];
 6 
 7 bool check(int x) {
 8     for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i]-x;
 9     long long Min=0;
10     for(int i=L;i<=n;i++) {
11         Min=min(Min,s[i-L]);
12         if(s[i]>=Min) return 1;
13     }
14     return 0;
15 }
16 
17 int main() {
18     scanf("%d%d",&n,&L);
19     int l=0,r=0;
20     for(int i=1;i<=n;i++) {
21         scanf("%d",&a[i]);
22         a[i]*=1000,r=max(r,a[i]);
23     } 
24     while(l<=r) {
25         int Mid=l+r>>1;
26         if(check(Mid)) l=Mid+1,ans=Mid;
27         else r=Mid-1;
28     }
29     printf("%d",ans);
30 }
31 /*
32 二分枚举平均值ave。
33 将每个数减去ave,看是否有长度不小于L的连续区间,使得这段区间的和大于等于0。
34 */

 

数列分段II

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,a[100005];
 4 
 5 bool check(int x) {
 6     int cnt=1,sum=a[1];
 7     for(int i=2;i<=n;i++) {
 8         sum+=a[i];
 9         if(sum>x) cnt++,sum=a[i];
10         if(cnt>m) return 0;
11     } return 1;
12 }
13 
14 int main() {
15     scanf("%d%d",&n,&m);
16     int l=0,r=0;
17     for(int i=1;i<=n;i++) {
18         scanf("%d",&a[i]);
19         l=max(l,a[i]),r+=a[i];
20     }
21     while(l<=r) {
22         int Mid=l+r>>1;
23         if(check(Mid)) r=Mid-1; 
24         else l=Mid+1;
25     }
26     printf("%d",l);
27 }
28 //二分答案

 

曲线

 1 #include<bits/stdc++.h>
 2 #define eps 1e-10
 3 using namespace std;
 4 int T,n;
 5 struct node{double a,b,c;}s[100005];
 6 inline int read() {
 7     int x=0,f=1; char c=getchar();
 8     while(c<0||c>9) {if(c==-)f=-1; c=getchar();}
 9     while(c>=0&&c<=9) x=(x<<3)+(x<<1)+c-0,c=getchar();
10     return x*f;
11 }
12 double F(double x) {
13     double f=-1e10;
14     for(int i=1;i<=n;i++)
15      f=max(f,s[i].a*x*x+s[i].b*x+s[i].c);
16     return f;
17 }
18 
19 int main() {
20     T=read();
21     while(T--) {
22         n=read();
23         for(int i=1;i<=n;i++)
24          s[i]=(node){read(),read(),read()};
25         double l=0,r=1000;
26         while(l+eps<=r) {
27             double Mid=(l+r)/2;
28             if(F(Mid)>=F(Mid+eps)) l=Mid;
29             else r=Mid;
30         }
31         printf("%.4lf
",F(l));
32     }
33 }
34 //二分枚举x 

 

以上是关于『一本通』二分与三分的主要内容,如果未能解决你的问题,请参考以下文章

信息学奥赛一本通Part1.2 基础算法-二分与三分

二分与三分

二分与三分(精度类型)

「一本通 1.2 练习 3」灯泡(三分/公式法)(三角函数,计算几何)

#10181. 「一本通 5.5 练习 2」绿色通道

#10013 曲线(三分)