Бесплатный урок с нашим репетитором!

Узнать подробнее

Новая Школа - онлайн-школа подготовки к ЕГЭ
При поддержке
Посмотреть все вопросы нейросети
Бесплатный пробный урок с репетитором

Узнай больше про репетиторов Новой Школы и запишись на бесплатный пробный урок. Мы проверим твой уровень знаний и составим план обучения по любому предмету и классу

Вопрос от Анонимного юзера 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. Теперь же двигаемся «по краям» и получаем линейную по времени реализацию после сортировки.

Если хочешь, могу привести тесты на нескольких примерах или разобрать конкретный набор данных из твоего примера.

Задай свой вопрос

Напиши любую задачу или вопрос, а нейросеть её решит

Похожие вопросы 15

Бесплатно Мобильное приложение ГДЗ
Мобильное приложение ГДЗ

Задавай вопросы искуcственному интеллекту текстом или фотографиями в приложении на iPhone или Android

qr-codegoogle-playapp-store

Саша — ассистент в телеграмме

На c++
Задача понятна: есть 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 и выше): ```cpp #include using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); long long n, k; if (!(cin >> n >> k)) return 0; vector 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. Теперь же двигаемся «по краям» и получаем линейную по времени реализацию после сортировки. Если хочешь, могу привести тесты на нескольких примерах или разобрать конкретный набор данных из твоего примера.