前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >假定一个解并判断是否可行(二分搜索应用)

假定一个解并判断是否可行(二分搜索应用)

作者头像
砖业洋__
发布2023-05-06 16:42:32
1060
发布2023-05-06 16:42:32
举报
文章被收录于专栏:博客迁移同步

                                                             Cable master (POJ No. 1064)

    有N条绳子,它们的长度分别为Li。如果从它们中切割出K条长度相同的绳子的话,这K条绳子每条最长能有多长?答案保留到小数点后2位。 限制条件:

1≤N≤10000

1≤K≤10000

1≤Li≤100000

输入:

N = 4

K = 11

L = {8.02,7.43,4.57,5.39}

输出

2.00(每条绳子分别可以得到4条、3条、2条、2条,共计11条绳子)

代码语言:javascript
复制
import java.util.Scanner;

public class Main {
    public static int N, K;
    public static double[] L = new double[100001];
    public static void main(String[] args) {
       Scanner cin = new Scanner(System.in);
       N = cin.nextInt();
       K = cin.nextInt();
       for (int i = 0; i < N; ++i) {
           L[i] = cin.nextDouble();
       }
       cin.close();
       solve();
    }
    public static void solve() {
        double lo = 0, hi = 100001; // 区间初始化的时候,只要使用足够大的数字INF,这里大于最长的绳子长度就可以,
        // 当然也可以Double.MAX_VALUE,64位,2的63次方,100次循环完全足够把精度确定到范围内)
        for (int i = 0; i < 100; ++i) {
            double mid = lo + ((hi - lo) >> 1);
            if (C(mid)) lo = mid; // 如果满足条件num>=K,说明切的绳子比较多,可以每一段再长一点,区间左端右移
            else hi = mid; // 如果不满足,说明每根绳子切的太长,不满足切出K条长度一样的绳子,区间右端左移
        }
        // 循环100次,精度有10的-31精度范围
        System.out.printf("%.2f", (Math.floor(hi * 100)) / 100);
    }
    public static boolean C(double x) {
        int num = 0;
        for (int i = 0; i < N; ++i) {
            num += (int)(L[i] / x);
        }
        return num >= K;
    }
}

这里for(int i= 0; i < 100;++i)也可以改成while(hi-lo>eps)这样的,但是如果eps太小了,就有可能因为浮点小数精度的原因导致陷入死循环。

在求解最大化或最小化的问题中,能够比较简单的判断条件是否满足,那么使用二分搜索可以很好的解决问题

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-03-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档