• 二分习题集


    二分水有点深、

    这个蛮不错的:你常写的二分查找,真的是没有bug吗?

    1、POJ2456 Aggressive cows (贪心加二分)

    在CSDN以前写过这篇博客:https://blog.csdn.net/qq_40889820/article/details/81675301

    这里改几发试试水

     所求间距d的范围:下界肯定是1(C<=N),上界不确定,用INF表示一个很大的常数

    a、(0,INF)

     b、(-INF,INF)(和上面是一样的,都是开区间)

     c、[1,INF)(左闭右开)

     该返回哪个值得调整一下。

     1 #include<iostream>
     2 #include<algorithm>
     3 using namespace std;
     4 int N,C;//N为牛舍的间数,C为牛的头数 
     5 const int MAX_N=100010;
     6 const int INF=1<<30;
     7 int x[MAX_N];//排序后x[i]表示第i间牛舍的位置 
     8 bool islegal(int d)//是否可以安排牛的位置使得任意牛的间距都不小于d
     9 {
    10      int last=1;//上一头牛所在的牛舍 ,第一头牛放在第一间牛舍 
    11      for(int i=1;i<C;i++)//C-1头牛
    12      {
    13              int crt=last+1;//当前牛所在的牛舍
    14              while(crt<=N&&x[crt]<x[last]+d) {crt++;}
    15              if(crt==N+1) return false;
    16              last=crt; 
    17      } 
    18      return true;
    19 } 
    20 int main()
    21 {  
    22     cin>>N>>C;
    23     for(int i=1;i<=N;i++) cin>>x[i];
    24     sort(x+1,x+N+1);
    25     int lb=1,ub=INF;
    26     //[1,INF)
    27     while(lb<ub)
    28     {
    29         int mid=(lb+ub)/2;
    30         if(islegal(mid)) lb=mid+1;
    31         else ub=mid;
    32     }
    33     cout<<lb-1;
    34 }
    View Code

    2、POJ1743 Musical Theme (后缀数组+二分)

    也写到后缀数组那儿了,两开花两开花:https://www.cnblogs.com/wangzhebufangqi/p/11317446.html

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAXN=2e4+5;
     4 const int INF=0x7fffffff;
     5 int str[MAXN];
     6 int sa[MAXN],ra[MAXN],height[MAXN];
     7 int wa[MAXN],wb[MAXN],wc[MAXN],wd[MAXN];
     8 int read()
     9 {
    10     int s=1,x=0;
    11     char ch=getchar();
    12     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
    13     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
    14     return x*s;
    15 }
    16 void GetSaRa(int n,int m)//倍增法 nlogn 
    17 {
    18     int i,j,p,*x=wa,*y=wb,*t;
    19     for(int i=0;i<m;++i) wd[i]=0;
    20     for(int i=0;i<n;++i) wd[x[i]=str[i]]++;
    21     for(int i=1;i<m;++i) wd[i]+=wd[i-1];
    22     for(int i=n-1;i>=0;--i) sa[--wd[x[i]]]=i;
    23     for(j=1,p=1;p<n;j*=2,m=p)
    24     {
    25         for(p=0,i=n-j;i<n;++i) y[p++]=i;
    26         for(i=0;i<n;++i) if(sa[i]>=j) y[p++]=sa[i]-j;
    27         for(i=0;i<n;++i) wc[i]=x[y[i]];
    28         for(i=0;i<m;++i) wd[i]=0;
    29         for(i=0;i<n;++i) wd[wc[i]]++;
    30         for(i=1;i<m;++i) wd[i]+=wd[i-1];
    31         for(i=n-1;i>=0;--i) sa[--wd[wc[i]]]=y[i];
    32         for(swap(x,y),p=1,x[sa[0]]=0,i=1;i<n;++i)
    33         x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++;
    34     }
    35 }
    36 void GetHeight(int n)
    37 {
    38     int i,j,k=0;
    39     for(i=1;i<=n;++i) ra[sa[i]]=i;
    40     for(i=0;i<n;height[ra[i++]]=k)
    41     for(k?k--:0,j=sa[ra[i]-1];str[i+k]==str[j+k];++k);
    42 }
    43 bool C(int n,int k)//是否存在两个长度为k的子串是相同的 
    44 {
    45     int maxi=-1,mini=1<<30;//下标 
    46     for(int i=1;i<=n;++i)
    47     {
    48         if(height[i]<k)//分组
    49         maxi=sa[i],mini=sa[i];
    50         else//组内是否有相同长度超过k的子串且距离大于k 
    51         {
    52             maxi=max(maxi,max(sa[i],sa[i-1]));
    53             mini=min(mini,min(sa[i],sa[i-1]));
    54             if(maxi-mini>k) return true;
    55         }
    56     }
    57     return false;
    58 }
    59 int main()
    60 {
    61     //freopen("1.txt","r",stdin);
    62     int n,x,tmp;
    63     while(scanf("%d",&n),n)
    64     {
    65         x=read();tmp=x;
    66         for(int i=1;i<n;++i)
    67         {
    68             x=read();
    69             str[i-1]=x-tmp+100;//差分,避免桶排序中出现负的下标多加个100 
    70             tmp=x; 
    71         }
    72         str[n-1]=0;n--;
    73         GetSaRa(n+1,300);
    74         GetHeight(n);
    75     //    for(int i=1;i<=n;++i) cout<<height[i]<<' ';cout<<endl;
    76         if(!C(n,4))
    77         {
    78             cout<<0<<endl;
    79             continue;
    80         }
    81         //(-1,INF)
    82         int l=-1,r=INF,mid;
    83         while(l+1!=r)
    84         {
    85             mid=(l+r)>>1;
    86             if(C(n,mid)) l=mid;
    87             else r=mid;    
    88         } 
    89         cout<<l+1<<endl;
    90     }
    91     return 0;
    92 }
    View Code

    开区间完事!

    3、2018SWERC Blurred Pictures (ST+二分)(HNU内网访问)

  • 相关阅读:
    canvas设置渐变
    canvas设置线条样式
    canvas给图形添加颜色
    Vue中父组件与子组件之间传值
    Vue实例的生命周期
    es6常用语法和特性
    JS基础:常用API
    JS基础:函数
    JS基础:闭包和作用域链
    JS基础:this的指向以及apply、call的作用
  • 原文地址:https://www.cnblogs.com/wangzhebufangqi/p/11328034.html
Copyright © 2020-2023  润新知