| Time Limit: 1000MS | Memory Limit: 10000K | |
| Total Submissions: 21181 | Accepted: 4571 | 
Description
Input
Output
Sample Input
4 11 8.02 7.43 4.57 5.39
Sample Output
2.00
Source
又是一个浮点数的二分题。题意是这样的,给n个木头棒子,然后他们的长度是l_i,分成k个等分,不允许边角料的拼接。求分成k等分之后的每份长度。
关键还是精度的问题。怎么说呢,因为浮点数的二分毕竟是与整数有区别的。这个区别又特别的恶心,就是搞不出来到底精度差在哪里,那后就不断的尴尬。。。
有一个解决这类浮点数二分的技巧,就是转化成整数的二分,同时新增一个res用于维护当前最大(小)限能够满足的题目要求的值。然后就是不断地更新左边界右边界,同时维护res就行了,当然最后返回res,确保精度。
这个题我放两份代码,分别是直接浮点数二分的(G++与C++分别提交均通过),还有整数二分的。
| 浮点二分法 /****
	*@author    Shen
	*@title     poj 1064
	*/
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const double eps = 1e-5;
int n, k;
double l, v[10005];
double maxa = 0;
bool test(double x)
{
    int sum = 0;
    for (int i = 0; i < n; i++)
        sum += int(v[i] / x);
    return sum >= k;
}
double Bsearch(double l, double r)
{
    while (r - l > eps)
    {
        double mid = (r + l) * 0.5;
        if (test(mid))
            l = mid;
        else r = mid;
    }
    return r;
}
void solve()
{
    maxa = 0;
    for (int i = 0; i < n; i++)
    {
        scanf("%lf", &l);
        v[i] = l;
        maxa = max(maxa, v[i]);
    }
    double ans = Bsearch(0.0, maxa);
    ans = 0.01 * int(ans * 100);
    //G++
        printf("%.2f\n", ans);
    //C++
    //  printf("%.2lf\n", ans);
}
int main()
{
    while (~scanf("%d%d", &n, &k))
        solve();
    return 0;
} | 
| 整数二分法 /****
	*@author    Shen
	*@title     poj 1064
	*/
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const double eps = 1e-5;
int n, k;
double l, v[10005];
double maxa = 0;
bool test(int x)
{
    int sum = 0;
    for (int i = 0; i < n; i++)
        sum += int(v[i] / x);
    return sum >= k;
}
int Bsearch(int l, int r)
{
    int res = 0;
    while (l <= r)
    {
        int mid = (r + l) / 2;
        //printf("l = %d, r = %d, mid = %d, res = %d.\n", l, r, mid, res);
        if (test(mid))
            res = max(res, mid), l = mid + 1;
        else r = mid - 1;
    }
    return res;
}
void solve()
{
    maxa = 0;
    for (int i = 0; i < n; i++)
    {
        scanf("%lf", &l);
        l *= 100.0;
        v[i] = l;
        maxa = max(maxa, v[i]);
    }
    int ans = Bsearch(1, int(maxa));
    printf("%d.%02d\n", ans / 100, ans % 100);
}
int main()
{
    while (~scanf("%d%d", &n, &k))
        solve();
    return 0;
} | 
POJ 1064 Cable master 浮点数二分,布布扣,bubuko.com
原文地址:http://blog.csdn.net/polossk/article/details/25406653