二分题目总结(未完待续)

二分的用处太大了,不管是求简单的方程,还是求最优解方面都是不错的解题思想。

只要在线性,顺序或者有序的数据里就可以用二分来找最优的答案,而且时间平均都是O(log2 n)。题目中好像是HDU 4190吧,这题的限时是10000ms,而用二分做才用时1000ms,其优点可想而知。

不过就像《编程珠玑》中说的一样,虽然二分思路及其做法很爽,但是编写二分的程序总是错漏百出的。二分的第一个程序出现在1942年,但是直到1962年出出现了第一个没有bug的二分程序,其编写正确难度可想而知。

解题技巧:

(1)整形数据题目:l 为下界,r 为上界

一般的整形数据的题其循环都是 :

while ( l < r )   然后l=mid+1,high=mid 这各形式的;

或者有的题目边界要求比较强就得是

while ( l <= r) 然后 l=mid+1,r=mid-1 这各形式;

还有道题就是CF 371C那道中的边界处理要求比较高就是:

while(  l+1 < r ) 然后 l=mid,r=mid

(2)浮点型题目: #define eps 1e-5

大神说的话:“一般浮点型题目都会与精度打交道,所以势必与eps有关,因为如果如果精度要求0.01,那么如果你在 l=mid+eps这样做的话,这里我设eps为0.00001,那么时间复杂度就会乘以10^3了,那么既然二分是减少时间的,这样又会增加时间复杂 度,那该怎么避免这个problem呢。

所以在HDU 1551这题上我就掉进了这个坑了,我把精度写在 l=mid+eps里了,然后直接TLE。  我把精度写在while里面的时候时间直接下降很多。因为每次都是平分,这就与eps没多大关系了,只要能接近最优答案就行。所以技巧如下:

while( r - l >eps)  然后 l=mid , r=mid;即可。”。

解题的基本思路就是:

while( l < r )
{
  mid=(l+r)/2; //如果是整数用移位>>1更加快
  if(gao(mid)<=m) l=mid+1;  //gao函数是处理二分枚举之后验证最佳答案是否符合的函数
  else r=mid;
}

下面是这些题的代码及分析:

HDU1551    Cable master   http://acm.hdu.edu.cn/showproblem.php?pid=1551

算是我的二分第一题吧,题意是给你n根绳子,让你分成长度相等m段,求绳子的最长长度。以前根本不知道这种题可以用二分来做,感觉很神奇。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <algorithm>
#define eps 1e-8
using namespace std;
int n,m;
double sum;
double a[10001];
bool judge(double s)
{
    int cnt=0;
    for(int i=0; i<n; i++)
    {
        cnt+=(int)(a[i]/s);//这根绳子可以分得段数
    }
    if(cnt>=m) return true;
    else return false;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
    {
        sum=0;
        for(int i=0; i<n; i++)
        {
            scanf("%lf",&a[i]);
            sum+=a[i];
        }
        sum/=m;//绳子可以分的最大长度
        double l=0,r=sum;
        while(fabs(r-l)>eps)
        {
            double mid=(l+r)/2.0;
            if(judge(mid))
                l=mid;
            else r=mid;
        }
        printf("%.2lf\n",l);
    }
    return 0;
}

时间: 2024-10-08 23:28:40

二分题目总结(未完待续)的相关文章

CareerCup All in One 题目汇总 (未完待续...)

Chapter 1. Arrays and Strings 1.1 Unique Characters of a String 1.2 Reverse String 1.3 Permutation String 1.4 Replace Spaces 1.5 Compress String 1.6 Rotate Image 1.7 Set Matrix Zeroes 1.8 String Rotation Chapter 2. Linked Lists 2.1 Remove Duplicates

第二章-第二题(练习使用git的add/commit/push/pull/fetch/clone等基本命令)-By郭青云(未完待续)

题目描述: 每人自己建立一个HelloWorld项目,练习使用git的add/commit/push/pull/fetch/clone等基本命令.比较项目的新旧版本的差别. 使用步骤: 未完待续...... 参考文件:http://blog.csdn.net/u012575819/article/details/50553501

bzoj2594水管局长数据加强版题解(未完待续)

题目大意 给一张带权无向图,无重边和自环,有如下操作: 删除某条边,保证这条边在删除前一定存在,并且不破坏原图连通性: 询问两点之间所有路径中最小权值的最大值是多少: 题解 问题的答案显然在原图的最小生成树上,于是本题就变成了动态维护删边最小生成树. 然而LinkCutTree维护最小生成树时并不支持删边操作,所以要离线处理,先删掉该删掉的边,再求最小生成树,把所有操作倒过来用LCT维护. 如何用LCT维护动态添边最小生成树 设原图中有n个点,m条边: 把每条边视为一个点,编号为n+1,n+2,

练武场之“封装、继承”攻略(未完待续)

如题: 使用继承编写Person.Student类 编写Person类: 属性有:姓名.年龄.出生日期 方法有:showInfo(); 编写Student类: 属性有:姓名.年龄.出生日期.学校 方法有:showInfo(); study(); 使用继承优化Student类. Ready Go! 第一步 Person类 1 package a; 2 //父类 3 public class Person { 4 // 为了让成员变量隐藏(封装),便于对值制定规则:否则变量会被直接赋值. 5 pri

whatweb.rb 未完待续

#!/usr/bin/env ruby #表示ruby的执行环境 =begin # ruby中用=begin来表示注释的开始 .$$$ $. .$$$ $. $$$$ $$. .$$$ $$$ .$$$$$$. .$$$$$$$$$$. $$$$ $$. .$$$$$$$. .$$$$$$. $ $$ $$$ $ $$ $$$ $ $$$$$$. $$$$$ $$$$$$ $ $$ $$$ $ $$ $$ $ $$$$$$. $ `$ $$$ $ `$ $$$ $ `$ $$$ $$' $ `$

把握linux内核设计思想系列(未完待续......)

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 把握linux内核设计思想(一):系统调用 把握linux内核设计思想(二):硬中断及中断处理 把握linux内核设计思想(三):下半部机制之软中断 把握linux内核设计思想(四):下半部机制之tasklet 把握linux内核设计思想(五):下半部机制之工作队列及几种机制的选择 把握linux内核设计思想(六):内核时钟中断 把握linux内核设计思想(七):内核定时器和

[译]App Framework 2.1 (1)之 Quickstart (未完待续)

最近有移动App项目,选择了 Hybrid 的框架Cordova  和  App Framework 框架开发. 本来应该从配置循序渐进开始写的,但由于上班时间太忙,这段时间抽不出空来,只能根据心情和兴趣,想到哪写到哪,前面的部分以后慢慢补上. App Framework 前生是是叫 jqMobi 注意大家不要和 jQuery Mobile 混淆了,它们是两个不同的框架,一开始我还真混淆了0.01秒. 这里我先翻译一下Quickstart 部分,一是自己工作上用的上,二是也想顺便练练英文,最关键

数据结构与算法之--高级排序:shell排序和快速排序【未完待续】

高级排序比简单排序要快的多,简单排序的时间复杂度是O(N^2),希尔(shell)排序的是O(N*(logN)^2),而快速排序是O(N*logN). 说明:下面以int数组的从小到大排序为例. 希尔(shell)排序 希尔排序是基于插入排序的,首先回顾一下插入排序,假设插入是从左向右执行的,待插入元素的左边是有序的,且假如待插入元素比左边的都小,就需要挪动左边的所有元素,如下图所示: ==> 图1和图2:插入右边的temp柱需要outer标记位左边的五个柱子都向右挪动 如图3所示,相比插入排序

git个人使用总结 —— idea命令行、撤销commit (未完待续)

近期在使用git,最开始在idea界面操作,后来要求用命令行.刚开始还不是很习惯,感觉很麻烦,用了几天后感觉爽极了! 其实git的命令也不是很多,熟悉一段时间就差不多能顺利使用了.使用过程中遇到了各种各样的问题,有些小问题就在这里集中总结一下. 1.idea命令行.git安装后就自带终端git bash,使用起来很方便.但是用idea开发,开发后还要在相应文件夹下打开git bash很麻烦.其实idea也带有终端terminal,在最下方可以找到,在这里就可以执行命令.但是如果是默认方式安装的g

Unity3D快捷键 未完待续

Unity3D 点选Object+F Object在当前视角居中 CTRL+1/2 Scene/Game视图的切换 MonoDevelop CTRL+K  删除光标所在行的该行后面的代码 CTRL + ALT +C  注释/不注释该行 CTRL+ DOWN  像鼠标滚轮一样向下拖 CTRL + UP 像鼠标滚轮一样向上拖 CTRL + F  查找该脚本 CTRL + SHIFT + F 查找全部脚本 CTRL + H 替换代码 CTRL + SHIFT +W 关掉所有脚本 Unity3D快捷键