Cable master(假定一個解並判斷是否可行)(POJ NO.1064)

Cable master
Time Limit: 1000MS
Memory Limit: 10000K

題目:

Description

Inhabitants of the Wonderland have decided to hold a regional programming contest. The Judging Committee has volunteered and has promised to organize the most honest contest ever. It was decided to connect computers for the contestants using a “star” topology - i.e. connect them all to a single central hub. To organize a truly honest contest, the Head of the Judging Committee has decreed to place all contestants evenly around the hub on an equal distance from it.
To buy network cables, the Judging Committee has contacted a local network solutions provider with a request to sell for them a specified number of cables with equal lengths. The Judging Committee wants the cables to be as long as possible to sit contestants as far from each other as possible.
The Cable Master of the company was assigned to the task. He knows the length of each cable in the stock up to a centimeter,and he can cut them with a centimeter precision being told the length of the pieces he must cut. However, this time, the length is not known and the Cable Master is completely puzzled.
You are to help the Cable Master, by writing a program that will determine the maximal possible length of a cable piece that can be cut from the cables in the stock, to get the specified number of pieces.

Input

The first line of the input file contains two integer numb ers N and K, separated by a space. N (1 = N = 10000) is the number of cables in the stock, and K (1 = K = 10000) is the number of requested pieces. The first line is followed by N lines with one number per line, that specify the length of each cable in the stock in meters. All cables are at least 1 meter and at most 100 kilometers in length. All lengths in the input file are written with a centimeter precision, with exactly two digits after a decimal point.

Output

Write to the output file the maximal length (in meters) of the pieces that Cable Master may cut from the cables in the stock to get the requested number of pieces. The number must be written with a centimeter precision, with exactly two digits after a decimal point.
If it is not possible to cut the requested number of pieces each one being at least one centimeter long, then the output file must contain the single number “0.00” (without quotes).

Sample Input

4 11
8.02
7.43
4.57
5.39

Sample Output

2.00

Source

Northeastern Europe 2001

題目大意:

有N條繩子,它們的長度分別爲Li。如果從它們中切割出K條長度相同的繩子的話,這K條繩子每條最長能有多長?答案保留到小數點後兩位。

分析:
這個問題用二分搜索可以非常容易的求得答案。
最優解的模板是:
“求滿足某個條件C(x)的最小的x”
對於任意滿足的C(x)的x,如果所有的x’>=x也滿足C(x’)的話,我們就可以用二分搜索來求得最小的x。首先我們將區間的左端點初始化爲不滿足C(x)的值,右端點初始化爲滿足C(x)的值。然後每次取中點mid=(ub+lb)>>2,判斷C(mid)是否滿足並縮小範圍,直到(lb,ub]足夠小了爲止。最後ub就是要求的最小值。最大化的問題也可以用同樣的方法。

此處的條件C(x):=可以得到K條長度爲x的繩子
則問題變成了求滿足C(x)條件的最大x,在區間初始化的時候,只需要使用充分大的INF>(MaxL)作爲上界即可:
lb=0;
ub=INF;
由於長度爲Li的繩子最多可以切出floor(Li/x)段長度爲x的繩子,因此
C(x)=(floor(Li/x)的總和是否大於等於K);

#include<cmath>

double ceil(double x);
 ceil(x)返回不小於x的最小整數值(然後轉換爲double型)
double floor(double x);
 floor(x)返回不大於x的最大整數值。
double round(double x);
 round(x)返回x的四捨五入整數值。

如果這道題不用floor(ub*100)/100,那麼直接輸出”%.2lf”那麼會直接四捨五入到兩位(用cout<

AC代碼:

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<string.h>
#include<iomanip>
#include<cmath>
using namespace std;
int N, K;
const int Max_N = 10001;
double L[Max_N];

bool C(double x)
{
    int cnt = 0;
    for (int i = 0; i < N; i++)
        cnt += int(L[i] / x);
    return cnt >= K;
}
int main()
{
    while (~scanf("%d%d",&N,&K))
    {
        memset(L, 0, sizeof(L));
        double maxl = 0;
        for (int i = 0; i < N; i++)
        {
            scanf("%lf", L+i);
            maxl = max(maxl, L[i]);
        }
        //for (int i = 0; i < N;i++)
        //cout << L[i] << endl;
        //二分

        double lb = 0, ub =2*maxl;
        double EPS = 0.001;
        while ((ub-lb)>EPS)//或者用for(int i=0;i<100;i++)循環100次精度可達10e-30(0.5^100)
        {
            double mid = (lb + ub) / 2;
            if (C(mid))lb = mid;
            else ub = mid;
        }
        printf("%.2f\n", floor(ub*100)/100);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章