二分查值,正确的姿势

04:网线主管

总时间限制: 
1000ms

内存限制: 
65536kB
描述

仙境的居民们决定举办一场程序设计区域赛。裁判委员会完全由自愿组成,他们承诺要组织一次史上最公正的比赛。他们决定将选手的电脑用星形拓扑结构连接在一起,即将它们全部连到一个单一的中心服务器。为了组织这个完全公正的比赛,裁判委员会主席提出要将所有选手的电脑等距离地围绕在服务器周围放置。

为购买网线,裁判委员会联系了当地的一个网络解决方案提供商,要求能够提供一定数量的等长网线。裁判委员会希望网线越长越好,这样选手们之间的距离可以尽可能远一些。

该公司的网线主管承接了这个任务。他知道库存中每条网线的长度(精确到厘米),并且只要告诉他所需的网线长度(精确到厘米),他都能够完成对网线的切割工作。但是,这次,所需的网线长度并不知道,这让网线主管不知所措。

你需要编写一个程序,帮助网线主管确定一个最长的网线长度,并且按此长度对库存中的网线进行切割,能够得到指定数量的网线。

输入
第一行包含两个整数N和K,以单个空格隔开。N(1 <= N <= 10000)是库存中的网线数,K(1 <= K <= 10000)是需要的网线数量。
接下来N行,每行一个数,为库存中每条网线的长度(单位:米)。所有网线的长度至少1m,至多100km。输入中的所有长度都精确到厘米,即保留到小数点后两位。
输出
网线主管能够从库存的网线中切出指定数量的网线的最长长度(单位:米)。必须精确到厘米,即保留到小数点后两位。
若无法得到长度至少为1cm的指定数量的网线,则必须输出“0.00”(不包含引号)。
样例输入
4 11
8.02
7.43
4.57
5.39
样例输出
2.00

思路:  避免精度问题,把单位全部*100换算成厘米,最后/100.0转成double。从最小的1厘米开始二分到Max,最大只能分到Max长度。  ans是取最大值,所以在左边界更新的时候更新。  一开始的用的求最后一个区间值得二分姿势,卡边界,只能得8到9分,边界开到1000w+10才能得10分。

有问题的代码,虽然AC了,但是其实是开足了边界:比如 1 10,找的是10,最后卡在9,10,这时候l=r-1,ans=l=9就退出二分了,这种二分姿势是第一道题的姿势。。这里明显是不对的
#include <iostream>
#include <cstdio>
#include <cmath>
#include <bits/stdc++.h>
const int maxn = 10000+10;
using namespace std;
int a[maxn];
int ans,n,k;

int check(int m) {
    int cnt = 0;
    for(int i = 1; i <= n; i++) {
        cnt += a[i]/m;
    }
    return cnt;
    }

void search(int l,int r) {

    int mid;
    while(l < r-1) {
        mid = (l+r)/2;
        if(check(mid)<k) {
            r = mid;
        }
        else if(check(mid)>=k) {
            ans = mid;
            l = mid;
        }

    }
    printf("%.2f\n",ans/100.0);
    }

int main()
{
//    freopen("in.txt","r",stdin);
    scanf("%d%d",&n,&k);
    int Max = -1;
    for(int i = 1; i <= n; i++) {
        double t;
        scanf("%lf",&t);
        a[i] = (int)(t*100);

        if(a[i]>Max) {
            Max = a[i];
        }
    }

    sort(a+1,a+1+n);
    search(1,10000010);

    return 0;
}

正确的姿势:

l<=r,利用左加1,右+1来偏移二分遍历所有情况最后退出条件。

注意这里的最低精度就是1厘米,如果不满住是进不了循环,ans默认值全局变量是0,/100.0隐式转换成double输出的是0.00

#include <iostream>
#include <cstdio>
#include <cmath>
#include <bits/stdc++.h>
const int maxn = 10000+10;
using namespace std;
int a[maxn];
int ans,n,k;

int check(int m) {
    int cnt = 0;
    for(int i = 1; i <= n; i++) {
        cnt += a[i]/m;
    }
    return cnt;
    }

void search(int l,int r) {

    int mid;
    while(l <= r) {
        mid = (l+r)/2;
        if(check(mid)<k) {
            r = mid-1;
        }
        else if(check(mid)>=k) {
            ans = mid;
            l = mid+1;
        }

    }
    printf("%.2f\n",ans/100.0);
    }

int main()
{
//    freopen("in.txt","r",stdin);
    scanf("%d%d",&n,&k);
    int Max = -1;
    for(int i = 1; i <= n; i++) {
        double t;
        scanf("%lf",&t);
        a[i] = (int)(t*100);

        if(a[i]>Max) {
            Max = a[i];
        }
    }

    sort(a+1,a+1+n);
    search(1,Max);

    return 0;
}

时间: 2024-10-01 23:28:52

二分查值,正确的姿势的相关文章

高版本jquery尤其是1.10.2的版本设置input radio设置值的最正确的姿势。

$("input:radio[name="analyshowtype"]").attr("checked",false); $("input[name=jizai]:eq(0)").attr("checked",'checked'); $("input[@type=radio][name=sex][@value=1]").attr("checked",true); 以

机器学习经典算法详解及Python实现--聚类及K均值、二分K-均值聚类算法

摘要 聚类是一种无监督的学习(无监督学习不依赖预先定义的类或带类标记的训练实例),它将相似的对象归到同一个簇中,它是观察式学习,而非示例式的学习,有点像全自动分类.说白了,聚类(clustering)是完全可以按字面意思来理解的--将相同.相似.相近.相关的对象实例聚成一类的过程.机器学习中常见的聚类算法包括 k-Means算法.期望最大化算法(Expectation Maximization,EM,参考"EM算法原理").谱聚类算法(参考机器学习算法复习-谱聚类)以及人工神经网络算法

《机器学习实战》之二分K-均值聚类算法的python实现

<机器学习实战>之二分K-均值聚类算法的python实现 上面博文介绍了K-均值聚类算法及其用python实现,上篇博文中的两张截图,我们可以看到,由于K-均值聚类算法中由于初始质心的选取,会造成聚类的局部最优,并不是全局最优,因此,会造成聚类的效果并不理想,为克服K-均值算法收敛于局部最小值的问题,就有了二分K-均值算法. 二分K-均值聚类算法 二分K均值算法是基本K均值算法的直接扩充,其基本思想是:为了得到K个簇,首先将所有点的集合分裂成两个簇,然后从这些簇中选取一个继续分裂,迭代直到产生

NSnotificationCenter 正确使用姿势, removeObject 探索

最近在做平板的过程中,发现了一些很不规范的代码.偶然修复支付bug的时候,看到其他项目代码,使用通知的地方没有移除,我以为我这个模块的支付闪退是因为他通知没有移除的缘故.而在debug和看了具体的代码的时候才发现和这里没有关系.在我印象中,曾经因为没有移除通知而遇到闪退的问题.所以让我很意外,于是写了个demo研究了下,同时来讲下NSNotificationCenter使用的正确姿势. NSNotificationCenter 对于这个没必要多说,就是一个消息通知机制,类似广播.观察者只需要向消

Gradle的依赖方式&mdash;&mdash;Lombok在Gradle中的正确配置姿势

写过java的都知道,lombok几乎在项目中处于不可或缺的一部分,但是lombok在Gradle的项目中配置并非人人都知道. 很多人在项目依赖中直接这样写 1 compile "org.projectlombok:lombok:1.18.4" 但这样的处理在Gradle 5.0以上被命令禁止了,在4.x的高级版本中编译时也会有对应的告警 12345 The following annotation processors were detected on the compile cla

养成良好的编程风格--论二分查找的正确姿势

摘自:http://www.cnblogs.com/ider/archive/2012/04/01/binary_search.html 在学习算法的过程中,我们除了要了解某个算法的基本原理.实现方式,更重要的一个环节是利用big-O理论来分析算法的复杂度.在时间复杂度和空间复杂度之间,我们又会更注重时间复杂度. 时间复杂度按优劣排差不多集中在: O(1), O(log n), O(n), O(n log n), O(n2), O(nk), O(2n) 到目前位置,似乎我学到的算法中,时间复杂度

iOS-----5分钟学会枚举的正确使用姿势-Enumeration宏

前言 Enum,枚举,相信大部分编程语言都有对应的枚举类型,功能可能有多有少,但是枚举最核心的功能是 "规范的定义代码中的状态.状态码.选项". 状态.状态码.选项 什么是状态:同时只能出现一个值(状态码就是他的值),比如这个ScrollView里的枚举: Objective-C 1 2 3 4 5 typedef NS_ENUM(NSInteger, UIScrollViewKeyboardDismissMode) { UIScrollViewKeyboardDismissModeN

HDU 5441——Travel——————【并查集+二分查界限】

Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1313    Accepted Submission(s): 472 Problem Description Jack likes to travel around the world, but he doesn’t like to wait. Now, he is tr

阿里巴巴Java开发手册正确学习姿势是怎样的?刷新代码规范认知

很多人都知道,阿里巴巴在2017发布了<阿里巴巴Java开发手册>,前后推出了很多个版本,并在后续推出了与之配套的IDEA插件和书籍. 相信很多Java开发都或多或少看过这份手册,这份手册有7个章节,覆盖了编程规约.异常日志.单元测试.安全规约.MySQL数据库.工程结构以及设计规约等方面. 这份规约可以说是覆盖了Java开发的方方面面,如果还有人没看的话,强烈建议大家好好看看,并且仔细研读. 手册中,有那么一些规则,是比较容易理解的.比如一些变量命名规范,有另外一些规则,是不太容易理解的,背