Processing math: 100%

Yukicoder067 よくある棒を切る問題(1)

問題概要

ユキさんはN本の棒を持っていて、i番目の棒の長さはLiです。
棒は(長さを分割する方向に)自由に切ることができますが、繋げることはできません。
ユキさんは同じ長さのK本の棒を作りたいのです。
作れるK本の棒の長さの最大値を求めるプログラムを書いて下さい。

N2105Li109K1010

yukicoder067

解法

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;
    }
Share Comments
���̃G���g���[���͂Ăȃu�b�N�}�[�N�ɒlj�