zoukankan      html  css  js  c++  java
  • 加强赛第一轮题解

    2017/3/7###

    类型:二分查找 二分搜索


    A

    POJ1064

    题意:给出n条线段,以米的单位给出,小数点后两位(精确到厘米),要你对这些线段裁剪,裁剪出m条等长的线段,并且让这些线段尽可能长另外线段的长度不能小于1厘米,如果筹不够m条,输出0.00。

    思路:二分搜索0~1e9之间的值,每次找到一个mid,判断mid是否符合题意。对于1e9的数据二分30次就足够找到答案,循环100次能够提高精度。

    新知识:double floor( double arg ); 在math头文件里,作用是“向下取整”,即取不大与arg的最大整数

    #include "iostream"
    #include "cstdio"
    #include "algorithm"
    #include "cmath"
    using namespace std;
    
    int n,k;
    double s[20000];
    // 传入长度m,判断 按m切割出现的段数sum余最少段数k的关系
    // 1.sum<=k 说明切割长度长
    // 2.sum>k  说明切割合适,但仍可能有更加优秀的方案
    bool judge(double m){
      int sum = 0;
      for(int i=0;i<n;i++){
        sum += (int)(s[i]/m);
      }
      return sum<k;
    }
    int main(){
      while(cin>>n>>k){
        for(int i=0;i<n;i++)  cin>>s[i] ;
        // 采用二分搜索
        double l=0 , r=0x3f3f3f3f , mid;
        for(int i=0;i<100;i++){
          mid = (l+r)/2;
          if(judge(mid)) r=mid;
          else           l=mid;
        }
        printf("%.2lf
    ",floor(r*100)*0.01);
      }
      return 0;
    }
    

    B

    POJ2456

    题意:农夫 John 建造了一座很长的畜栏,它包括N (2 <= N <= 100,000)个隔间,这些小隔间依次编号为x1,…,xN (0 <= xi <= 1,000,000,000).
    但是,John的C (2 <= C <= N)头牛们并不喜欢这种布局,而且几头牛放在一个隔间里,他们就要发生争斗。为了不让牛互相伤害。John决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是什么呢?

    思路:此问题是寻找一个最大的最小距离,使得C头牛任意两头之间的最短距离最大值。两头牛之间的距离最短为0,最长为两端牛的距离,因此只需要二分0~Max_Len,寻找中间值mid。对于中间值mid我们需要检查符合 temp+mid<=x[i] 的次数,因为mid相当于当前任意两头牛之间的最短距离最大值,如果之前已经分配牛的位置加上现在最短距离最大值还要比X[i]小的话,那么X[i]位置处便可以放置一头牛(cnt++),最后比较按照mid为最短距离最大值放置牛的个数cnt和C的大小关系,如果cnt<C说明mid值取大了,r=mid,反之l=mid。

    #include "iostream"
    #include "cstdio"
    #include "algorithm"
    using namespace std;
    
    const int M = 1e6;
    int n,c;
    int s[M];
    // 1.cnt<c  说明二分的距离m大了
    // 2.cnt>=c 说明二分的距离m小了
    bool check(int mid){
      int cnt = 1;
      // tmp是之前的放置牛位置
      int tmp = s[0];
      for(int i=1;i<n;i++){
        if(tmp+mid<=s[i])  cnt++ , tmp=s[i];
      }
      // 下面代码有错误,为什么会出错呢?
      // 仔细分析这两段代码是能够发现其中的区别的!
      // 
      // for(int i=1;i<n;i++){
      // if(s[i]-s[i-1]>=m) cnt++;
      // }
      
      return cnt<c;
    }
    
    int main(){
      while(scanf("%d%d",&n,&c )!=EOF){
        for(int i=0;i<n;i++) cin>>s[i];
        sort(s,s+n);
        int l = 0 , r = (s[n-1]-s[0]+1) , mid;
        // 二分最大距离得到一个合适的最小距离
        while(r-l>1){
          mid = (l+r)/2;
          if(check(mid)) r=mid;
          else l=mid;
        }
        cout<<l<<endl;
      }
      return 0;
    }
    

    C

    POJ3258

    题意: 牛要到河对岸,在与河岸垂直的一条线上,河中有N块石头,给定河岸宽度L,以及每一块石头离牛所在河岸的距离,现在去掉M块石头,要求去掉M块石头后,剩下的石头之间以及石头与河岸的最小距离的最大值。

    思路:这个题和POJ2456相似,从N个石头中取出M个石头使得剩下石头之间的最小距离的值最大。也就是说需要在N块石头中找到N+1-M块石头,让它们之间的最小距离最大。

    我们用类比的方法就能很好的理解这道题,这道题中的N块石头相当于B题中的N个隔间,去掉M块石头后剩余N+1-M个石头(加上河岸两端)就相当于B题中的C头牛。B题是在N个隔间里尽量相隔远来放置C头牛,此题是在N块石头间尽量相隔较远来放置N+1-M块石头。

    两端河岸相当于两块石头,也就是D[0]=0 , D[N+1]=L。首先用二分枚举石头之间的最小距离最大值mid,每次都检测 temp+mid<=D[i],temp是之前选定的石头,就相当于从temp跳跃过来,如果之前石头的位置 + 现在枚举的最短距离最大值 <= 下个石头位置,也就是说现在的mid的确是比D[i]到temp的距离要小的,记录下来相邻距离小于等于mid的块数cnt 和 N+1-M比较,如果cnt<N+1-M说明mid值取大了,反正mid取小了

    #include "iostream"
    #include "algorithm"
    #include "cstdio"
    using namespace std;
    
    int L,N,M;
    int D[50000+10];
    
    bool check(int mid){
      int cnt = 0;  // cnt记录传入的mid能够去掉石头数
      int tmp = 0;  // s[0] = 0;
      for(int i=1;i<=N+1;i++){
        // 最小距离+之前点到岸边的距离<=D[i]
        if(mid+tmp<=D[i]) cnt++,tmp=D[i];
      }
      return cnt >= N+1-M;
    }
    int main(){
      while (cin>>L>>N>>M) {
        for(int i=1;i<=N;i++) cin>>D[i];
        D[0] = 0 , D[N+1] = L;
        // 排一下石头到河边的距离D
        sort(D+1,D+N+1);
        int l = 0 , r = 1e9;
        while(r-l>1){
          int mid = (l+r)/2;
          if(check(mid))  l=mid;
          else  r=mid;
        }
        cout<<l<<endl;
      }
      return 0;
    }
    

    如要转载请注明转载出处:http://www.cnblogs.com/WArobot
  • 相关阅读:
    php无刷新上传图片和文件
    wamp(win1064位家庭版+apache2.4.20+php5.5.37+mysql5.5.50)环境搭建
    linux下常见解压缩命令
    nginx虚拟主机配置小结
    Nginx下配置ThinkPHP的URL Rewrite模式和pathinfo模式支持
    iframe 高度自适应/以及在ie8中空白问题
    小程序-调用公共js对象方法/ app.js
    小程序-tabbar相关样式设置
    微信小程序连接无法跳转/ can not navigate to tabBar page错误
    微信小程序-tabBar无法显示问题解析
  • 原文地址:https://www.cnblogs.com/WArobot/p/6523584.html
Copyright © 2011-2022 走看看