問題の説明
Nロープは、公知のロープ当たり少なくとも1メートル、各ロープがKに同じロープの長さから一定の長さ(単位m)で、カットを有し、Kは、この最大のエネルギーを見つける方法を各ロープ長いですか?0.00答えが(例えば2はすなわち廃棄全ての後の数字1.799999 1.79ダウン予約されているなど)は、2つの小数点以下の桁数まで保持出力を満たさない場合、ロープの長さは、以下1センチメートル以下です。
図1に示すように、ここで思い出させるために、Cタイトルの要件は、2つの小数点以下の桁数までであり、それは(%。2Fは、2つの小数点以下の桁数に丸められる)%.2f直接使用することができません
入力
二つの入力ライン数N、K(1 <= N、K <= 10000)があります。
2行目の数N、各ロープの長さ(1 <=リー<= 100000)は、各入力は、二つの小数点以下の桁数を有しています。
%のLF、scanf関数の入力と出力は%fと入力し、二重。
出力
(2小数点以下の桁ダウン)状態最長の長さを満たす出力ロープ。
SampleInput
4 11
8.02
7.43
4.57
5.39
SampleOutput
2.00
この問題は、それを解決するための二分法を考えることはできません困難です。唯一のN 1E4が、関与小数が、暴力的な場合には、それは非常に可能性があること1E4 1E5 1E2、血液T. だから、半分は、時間、精神的地方、ハーフボードの保存、すべての可能な解決策を通過すると、コンピュータはわずかに質問の意味に変更することが、自分自身を実行してみましょう。ノートは、BBコードのキーではないくらいです。
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <math.h>
#include <iostream>
#include <string.h>
const int MAX=1e4+5;
using namespace std;
typedef long long ll;
double len[MAX];
double td(int n, double k)
{
double l=0, r=200000, m; /// 左右界尽量往两边拓,不要太多也不要刚刚好,怕极
///限数据,两边的值没被遍历到
int cnt, i, j;
for (j=0; j<250; j++)/// 因为是小数,不要用while(l<r),直接给它指定多次循环,
{ ///来保证答案的准确性,至于到底来几次,参考2^n >= 1e11
m = (l+r)/2;
cnt = 0; /// 每一次判断都记得要把cnt初始化
for (i=0; i<n; i++)
cnt += (int)(len[i]/m);/// cnt记下临时解m带来的结果,和k去进行比较
/// 这里没有cnt==k的return,和上面j的循环同理,毕竟要求最大解,cnt是向下取整
///的,很可能还没取到最大解,就直接满足条件return了
if (cnt<k)/// 小于说明绳子割长了,把右边界往左缩
r = m;
else /// 大于(等于放哪都一样)说明绳子割短了,再割长点试试
l = m;
}
return r; /// 要最大解,把最终的右边界返回。至于正常的二分查找的返回值,
} ///我再研究研究,搞懂了再去二分法板子那里更新
int main()
{
int N, K, i, j;
cin >> N >> K;
for (i=0; i<N; i++)
scanf ("%lf", &len[i]);
double ans=td(N, K)*100;/// 题目说了不四舍五入,所以我用了土办法,取几位我
ans = (int)ans; ///乘几位,然后向下取整,最后再除回去
ans /= 100;
printf("%.2f", ans); ///这时候不用担心会四舍五入了,小数点后两位后都是0
return 0;
}