1654 - 랜선 자르기

solution

code

#include <iostream>
using namespace std;

int main()
{
    // input
    int number_of_cable;
    int required_cable;
    cin >> number_of_cable;
    cin >> required_cable;
    int * current_cable_length = new int[number_of_cable];
    for(int i = 0; i < number_of_cable; i++)
        cin >> current_cable_length[i];

    // figure longest cable
    long long int longest_cable_index = 0;
    for(int i = 1; i < number_of_cable; i ++)
        longest_cable_index = (current_cable_length[longest_cable_index] < current_cable_length[i]) ? i : longest_cable_index;
    long long int longest_cable_length = current_cable_length[longest_cable_index];

    // step 1 - set bottom edge
    int piece = 0;
    long long int current_divided_cable = longest_cable_length;
    while(piece < required_cable)
    {
        for(int i = 0; i < number_of_cable; i++)
            piece += current_cable_length[i] / current_divided_cable;
        if(piece < required_cable) 
        {
            current_divided_cable /= 2;
            piece = 0;
        }
    }

    // step 2 - search optimal value from bottom edge to top edge, top edge = bottom edge * 2
    long long int previous_diveded_cable = current_divided_cable * 2;
    long long int middle_value = (previous_diveded_cable + current_divided_cable) / 2;
    piece = 0;
    while((current_divided_cable != middle_value) && (previous_diveded_cable != middle_value))
    {
        for(int i = 0; i < number_of_cable; i++)
            piece += current_cable_length[i] / middle_value;
        if(piece < required_cable)
        {
            previous_diveded_cable = middle_value;
            middle_value = (current_divided_cable + middle_value) / 2;
        }
        else
        {
            current_divided_cable = middle_value;
            middle_value = (middle_value + previous_diveded_cable) / 2;
        }
        piece = 0;
    }

    // print output
    cout << current_divided_cable << endl;

    return 0;
}

ref

1654번: 랜선 자르기