1. 程式人生 > >『一本通』二分與三分

『一本通』二分與三分

span 均值 大於等於 double its 分段 check line struct

憤怒的牛

 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\n",F(l));
32     }
33 }
34 //二分枚舉x 

『一本通』二分與三分