Вопрос от Анонимного юзера 09 сентября 2025 11:51
На c++

Ответ нейросети
09 сентября 2025 11:51
Задача понятна: есть n офисов с заданной высотой(a1…an). За один заказ можно увеличить или уменьшить высоту любого офиса на 1 этаж. Всего есть k заказов. Нужно минимизировать разницу между самым высоким и самым низким офисом после выполнения не более k заказов.
Подход (пошагово, понятно для школьников):
- Сначала отсортируем массив высот. Тогда изначальный минимум будет в начале, максимум — в конце.
- Будем работать «с краёв»: поднимем минимальные высоты или опустим максимальные, чтобы сузить диапазон.
- Пусть текущие минимальная высота L и максимальная R. Посчитаем:
- cntL — сколько офисов на минимальном уровне L (количество элементов равных L в левом краю).
- cntR — сколько офисов на максимальном уровне R (количество элементов равных R в правом краю).
- Сравниваем cntL и cntR:
- Если cntL ≤ cntR, выгоднее поднимать все офисы на уровне L до следующего различия. Следующий уровень — следующая за L высота в массиве. Стоимость такого подъёма: deltaL * cntL, где deltaL — разница между следующей высотой и текущей L.
- Иначе выгоднее опускать все офисы на уровне R до предыдущего различия. Стоимость: deltaR * cntR, где deltaR — разница между текущей R и предыдущей высотой.
- Если стоимость полностью помещается в оставшиеся k заказов, обновляем L или R соответственно и повторяем процесс (переходим к следующей группе одинаковых высот).
- Если же затрат слишком много, используем остаток k: поднимаем L на floor(k / cntL) или опускаем R на floor(k / cntR), и выходим.
- Итоговая разница: max(0, R - L).
Сложность: сортировка O(n log n) и один проход сдвигающихся границ — O(n). Используются long long для больших чисел.
Пример кода на C++ (совместим с компиляторами с C++17 и выше):
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long n, k;
if (!(cin >> n >> k)) return 0;
vector<long long> a(n);
for (long long i = 0; i < n; ++i) cin >> a[i];
sort(a.begin(), a.end());
long long i = 0; // левая граница (индекс текущего минимального блока)
long long j = n - 1; // правая граница (индекс текущего максимального блока)
long long L = a[i], R = a[j];
while (L < R && k > 0) {
// посчитаем количество элементов на минимальном уровне L
long long i2 = i;
while (i2 <= j && a[i2] == L) ++i2;
long long cntL = i2 - i; // сколько элементов имеют высоту L
// посчитаем количество элементов на максимальном уровне R
long long j2 = j;
while (j2 >= i && a[j2] == R) --j2;
long long cntR = j - j2; // сколько элементов имеют высоту R
if (cntL <= cntR) {
// поднимаем левый блок до следующего distinto уровня
if (i2 > j) break; // все элементы уже учтены, выход
long long nextL = a[i2];
long long delta = nextL - L;
long long cost = delta * cntL;
if (cost <= k) {
k -= cost;
i = i2;
L = nextL;
} else {
long long inc = k / cntL;
L += inc;
k -= inc * cntL;
break;
}
} else {
// опускаем правый блок до предыдущего distinto уровня
if (j2 < i) break; // все элементы уже учтены, выход
long long prevR = a[j2];
long long delta = R - prevR;
long long cost = delta * cntR;
if (cost <= k) {
k -= cost;
j = j2;
R = prevR;
} else {
long long dec = k / cntR;
R -= dec;
k -= dec * cntR;
break;
}
}
}
long long answer = (R > L) ? (R - L) : 0;
cout << answer << "\n";
return 0;
}
Пояснения по коду:
- Сортировка нужна, чтобы сгруппировать одинаковые высоты в начале и в конце.
- i и j — индексы границ текущего диапазона. L и R — текущие минимальная и максимальная высоты внутри этого диапазона.
- В каждом шаге считаются cntL и cntR — сколько офисов имеют минимальную и максимальную высоты на текущем крае.
- В зависимости от того, какая сторона “массивнее”, выбирается более выгодная цель поднимать/опускать. Если хватает бюджета, переходим к следующей границе; иначе делаем максимально возможное шаговое изменение и выходим.
Примечания и варианты:
- Если k достаточно большой, можно полностью выровнять все высоты, и разница станет 0.
- Альтернативный подход: бинарный поиск разности D и проверка минимального количества операций, чтобы привести все высоты в интервал длиной D. Теперь же двигаемся «по краям» и получаем линейную по времени реализацию после сортировки.
Если хочешь, могу привести тесты на нескольких примерах или разобрать конкретный набор данных из твоего примера.
Понравился ответ?
Задай свой вопрос
Напиши любую задачу или вопрос, а нейросеть её решит



