zoukankan      html  css  js  c++  java
  • POJ1064 Cable master 【二分找最大值】

    题目:题目太长了!

    https://vjudge.net/problem/POJ-1064

    题意分析:给了你N根长度为小数形式的棍子,再给出了你需要分的棍子的数量K,但要求你这K根棍子的长度必须是一样长的。需要你求解出满足题意的最长可能的棍子长度。根据二分找最大值的应用写即可。

    需要注意的是:

    1.注意题目给的范围是All cables are at least 1 meter and at most 100 kilometers in length;

    2.在写满足条件的函数时,对于int强制转换类型的应用,一定要注意后面的括号;(起初这里WA的)

    3.因为是找最大值,所以用right;

    4.100次循环的二分写法可以达到2^100,即可以达到10^30,足够了。

    代码:

     

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    using namespace std;
    const int MAXN = 1e4+5;
    int N, K;
    double Data[MAXN];
    
    bool fun(double x)
    {
        int cnt = 0;
        for(int i = 0; i < N; i++)
            cnt += (int)(Data[i]/x); //cnt += (int)Data[i]/x; WA
        if(cnt >= K)
            return true;
        else
            return false;
    }
    
    void solve()
    {
        double left = 0, right = 100001;
        double mid;
        for(int i = 0; i < 100; i++)
        {
             
            mid = (left+right)/2;
            if(fun(mid))
                left = mid;
            else
                right = mid;
        }
        printf("%.2f
    ", floor(right*100)/100);
    }
    
    int main()
    {
        while(~scanf("%d %d", &N, &K) )
        {
            for(int i = 0; i < N; i++)
                scanf("%lf", &Data[i]);
            solve();
        }
    
        return 0;
    }
    

     对于第二种二分写法,需要注意的是在用exp的时候,exp不能取太少,同时不要用小的左值去减右值,最好是用一个正值去和exp进行比较判断。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #define exp 1e-5
    using namespace std;
    const int MAXN = 1e4+5;
    double Data[MAXN];
    int N, K;
    
    bool fun(double x)
    {
        int cnt = 0;
        for(int i = 0; i < N; i++)
            cnt += (int)(Data[i]/x);
        return cnt >= K;
    }
    
    void solve()
    {
        double left = 0, right = 100000, mid;
        while(right - left > exp)   // **while(left - right < exp)
        {
            mid = (left + right)/2;
            if(fun(mid))
                left = mid;
            else
                right = mid;
        }
        printf("%.2f", floor(right*100)/100);
    }
    
    int main()
    {
        while(~scanf("%d %d", &N, &K))
        {
            for(int i = 0; i < N; i++)
            {
                scanf("%lf", &Data[i]);
            }
            solve();
        }
    
        return 0;
    }
    

      

      

     

      

  • 相关阅读:
    Handler类简介
    Collections 类
    git
    Java NIO总结
    Java I/O随笔
    Java可变参数
    Java静态导入
    Java I/O流体系中常见的流分类
    设计模式之简单工厂模式(Java)
    PL/SQL学习笔记
  • 原文地址:https://www.cnblogs.com/dybala21/p/9671812.html
Copyright © 2011-2022 走看看