zoukankan      html  css  js  c++  java
  • 『一本通』二分与三分

    传送门:《信息学奥赛一本通》提高版题解索引


    愤怒的牛

     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 
     7 double F(double x) {
     8     double f=-1e10;
     9     for(int i=1;i<=n;i++)
    10      f=max(f,s[i].a*x*x+s[i].b*x+s[i].c);
    11     return f;
    12 }
    13 
    14 int main() {
    15     T=read();
    16     while(T--) {
    17         n=read();
    18         for(int i=1;i<=n;i++)
    19          s[i]=(node){read(),read(),read()};
    20         double l=0,r=1000;
    21         while(l+eps<=r) {
    22             double Mid=(l+r)/2;
    23             if(F(Mid)>=F(Mid+eps)) l=Mid;
    24             else r=Mid;
    25         }
    26         printf("%.4lf
    ",F(l));
    27     }
    28 }
    29 //二分枚举x

     扩散

     1 #include<bits/stdc++.h>
     2 #define N 55
     3 using namespace std;
     4 int T,n,ans,x[N],y[N],fa[N];
     5 int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}
     6 
     7 bool check(int t) {
     8     for(int i=1;i<=n;i++) fa[i]=i;
     9     for(int i=1;i<n;i++)
    10      for(int j=i+1;j<=n;j++) {
    11         int d=abs(x[i]-x[j])+abs(y[i]-y[j]); //曼哈顿距离
    12         if(d<=2*t) { //不超过时间的2倍(两个点都能扩散) 
    13             int fi=find(i),fj=find(j);
    14             if(fi!=fj) fa[fi]=fj;
    15         }
    16      }
    17     int tot=0;
    18     for(int i=1;i<=n;i++) if(fa[i]==i) tot++;
    19     if(tot==1) return 1; //如果只有一个联通块 
    20     return 0;
    21 }
    22 
    23 int main() {
    24     scanf("%d",&n);
    25     for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
    26     int l=0,r=1e9;
    27     while(l<=r) { //二分答案 
    28         int Mid=l+r>>1;
    29         if(check(Mid)) r=Mid-1,ans=Mid;
    30         else l=Mid+1;
    31     }
    32     printf("%d",ans);
    33 }

    灯泡

     

     1 #include<bits/stdc++.h>
     2 #define eps 1e-8 
     3 using namespace std;
     4 int T;
     5 double D,H,h;
     6 double F(double x) {return D-x+H-(H-h)*D/x;} 
     7 
     8 int main() {
     9     scanf("%d",&T);
    10     while(T--){
    11         scanf("%lf%lf%lf",&H,&h,&D);
    12         double l=D*(H-h)/H,r=D; //或 l=D-D*h/H
    13         while(r-l>eps) {
    14             double M1=(l+r)/2.0;
    15             double M2=(M1+r)/2.0;
    16             if(F(M1)<F(M2)) l=M1; else r=M2;
    17         }
    18         printf("%.3lf
    ",F(l));
    19     }
    20 }

    传送带

     1 #include<bits/stdc++.h>
     2 #define eps 1e-6
     3 using namespace std;
     4 int P,Q,R;
     5 struct node{double x,y;}A,B,C,D,a,b;
     6 double dis(node a,node b) {
     7     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     8 }
     9 
    10 double cal(double p1,double p2) {
    11     a.x=A.x+(B.x-A.x)*p1;
    12     a.y=A.y+(B.y-A.y)*p1;
    13     b.x=C.x+(D.x-C.x)*p2;
    14     b.y=C.y+(D.y-C.y)*p2;
    15     return dis(A,a)/P+dis(a,b)/R+dis(b,D)/Q;
    16 }
    17 
    18 double get(double x) {
    19     double l=0,r=1;
    20     while(r-l>eps) {
    21         double M1=l+(r-l)/3.0,M2=r-(r-l)/3.0;
    22         if(cal(x,M1)>cal(x,M2)) l=M1; else r=M2;
    23     }
    24     return cal(x,l);
    25 }
    26 
    27 int main() {
    28     cin>>A.x>>A.y>>B.x>>B.y;
    29     cin>>C.x>>C.y>>D.x>>D.y;
    30     cin>>P>>Q>>R;
    31     double l=0,r=1;
    32     while(r-l>eps) {
    33         double M1=l+(r-l)/3.0,M2=r-(r-l)/3.0;
    34         if(get(M1)>get(M2)) l=M1; else r=M2;
    35     }
    36     printf("%.2lf",get(l));
    37 }
    38 //三分(a点)套三分(b点) 

    完结 (2019.1.29)

  • 相关阅读:
    Mysql 创建外键 1005 err 150
    骑车目标
    windows 如何查看端口占用进程ID 进程名称 强制结束进程
    Eclipse去除JavaScript验证错误
    MyEclipse 代码里的中文字太小设置方法
    security自动登陆
    Tomcat 7 可以修改 Session 默认的 Cookie 名 JSESSIONID 了
    windows2008 安装oracle10g“程序异常终止。发生内部错误。请将以下文件提供给oracle技术支持部门
    ORA-01652: 无法通过 128 (在表空间 TEMP 中) 扩展 temp 段(EXP-00056: 遇到 ORACLE 错误 1652 ORA-01652: unable to extend temp segment by 128 in tablespace TEMP)
    oracle数据库启动时出现ORA-01157和ORA-01110问题
  • 原文地址:https://www.cnblogs.com/qq8260573/p/10331491.html
Copyright © 2011-2022 走看看