Hướng dẫn giải của Bedao Mini Contest 21 - Cắt dây


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Tác giả: kazamahoang

Subtask ~1~: Ta luôn chia đôi sợi dây dài nhất.

Subtask ~2~: Giả sử ~x~ là giá trị làm tròn lên của đáp án. Ta đảm bảo được rằng có thể cắt các sợi dây để cho ra giá trị ~x~, ~x + 1~, ~x + 2~, ... Nhưng không thể cắt các sợi dây để cho ra giá trị nhỏ hơn hoặc bằng ~x - 1~. Vậy nên ta không cần quan tâm đến số thực, ta chỉ cần quan tâm giá trị nguyên ~x~ nhỏ nhất mà ta có thể cắt các sợi dây ra, sau ~k~ phép cắt dây, sao cho sợi dây có độ dài lớn nhất ~\le x~.

Cách làm ở subtask này là duyệt qua mọi giá trị ~x~, kiểm tra xem có thể cắt sao cho độ dài lớn nhất ~\le x~ hay không. Với mỗi sợi dây, ta sẽ tính số phép cắt cần ít nhất là ~\lceil \frac{A_i}{x} \rceil~. Nếu tổng các phép cắt cần thiết lớn hơn ~k~ thì không thoả mãn. Ngược lại ta sẽ luôn cắt được.

Subtask ~3~: Sử dụng phương pháp tìm kiếm nhị phân.

Code mẫu

#include<bits/stdc++.h>

#define int long long
#define pb push_back
#define fi first
#define se second
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int maxN = 1e6 + 5;
const int mod = 1e9 + 7;
const ll oo = 1e18;
int n, k;
int a[maxN];
void ReadInput()
{
    cin >> n >> k;
    for(int i=1; i<=n; i++)
        cin >> a[i];
}
bool chk(int val)
{
    int cnt = 0;
    for(int i=1; i<=n; i++)
    {
        cnt += (a[i] - 1) / val;
    }
    return cnt <= k;
}
void Solve()
{
    int low = 1, high = oo, mid;
    while(low <= high)
    {
        mid = (low + high) / 2;
        if(chk(mid)) high = mid - 1;
        else low = mid + 1;
    }
    cout << low;
}
int32_t main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    ReadInput();
    Solve();
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.