Codeforces Round 809 (Div. 2) D1. Chopping Carrots (Easy Version) 题解

发布时间 2023-11-14 15:46:45作者: 1v7w

题意

Codeforces Round 809 (Div. 2) D1. Chopping Carrots (Easy Version)

给两个整数\(n, k\), 一个数组 \(a\), 要求构造一个同样长度的数组 \(p\), 使得 \(\max\limits_{1 \le i \le n}\left(\left \lfloor \frac{a_i}{p_i} \right \rfloor \right) - \min\limits_{1 \le i \le n}\left(\left \lfloor \frac{a_i}{p_i} \right \rfloor \right)\) 最小,其中 \(p_i \le k\) 。输出最小值。

思路

我们可以设定变化后的数组最小值为 \(v = 0, 1, 2, ..., a_1\) ,这里 \(a_1\) 表示数组 \(a\) 最小值。接着依次求解在当前情况下 \(a_i\) 最小为多少(\(a_i \ge v\)的情况下),记录 \(a_i\) 的最大值和最小值,枚举完后用最大值减最小值更新答案。

代码

#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>

#define fi first
#define se second

using namespace std;
using ll = long long;
using pii = pair<int, int>;

const double eps = 1e-4;
const int N = 3010;
int n, k;
int a[N];

void solve() {
    scanf("%d%d", &n, &k);
    for (int i=1; i<=n; i++) {
        scanf("%d", &a[i]);
    }
    sort(a + 1, a + 1 + n);
    int res = 1e9;
    for (int v = 0; v <= a[1]; v++) {
        int maxv = 0, minv = 1e9;
        for (int i = 1; i<=n; i++) {
            int p = k;
            if (v) p = min(k, a[i] / v);
            maxv = max(maxv, a[i] / p);
            minv = min(minv, a[i] / p);
        }
        res = min(res, maxv - minv);
    }
    printf("%d\n", res);
}

int main() {
    // multiple case
    int t; scanf("%d", &t);
    while(t--) {
        solve();
    }

    // single case
    // solve();

    return 0;
}