問題概要
ユキさんはN本の棒を持っていて、i番目の棒の長さはLiです。
棒は(長さを分割する方向に)自由に切ることができますが、繋げることはできません。
ユキさんは同じ長さのK本の棒を作りたいのです。
作れるK本の棒の長さの最大値を求めるプログラムを書いて下さい。
N≦2∗105、Li≦109、K≦1010
解法
f(x):=長さxの棒をK本以上作れるかとすると小さいxについて連続して成立する性質があるので、これを二分探索する。
計算量:O(NlogK)
ソース
#include <bits/stdc++.h> using namespace std; using VS = vector<string>; using LL = long long; using VL = vector<LL>; using VVL = vector<VL>; #define SZ(a) int((a).size()) #define FOR(i, s, e) for (int(i) = (s); (i) < (e); (i)++) bool f(double x, LL K, VL& L) { LL ret = 0; FOR(i, 0, SZ(L)) { ret += L[i] / x; } return ret >= K; } LL N; int main() { cin.tie(0); ios_base::sync_with_stdio(false); cin >> N; VL L(N); FOR(i, 0, N) { cin >> L[i]; } LL K; cin >> K; double ok = 0; double no = 1e11; FOR(i, 0, 100) { double mid = (no - ok) / 2 + ok; if (f(mid, K, L)) { ok = mid; } else no = mid; } double ans = ok; cout << fixed << setprecision(10) << ans << "\n"; return 0; }