Редакция для Первая позиция отрицательного баланса
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
1. Идея
Нужно найти первую позицию, на которой сумма всех элементов от начала массива до этой позиции становится отрицательной.
Так как каждое событие меняет баланс на +1 или -1, достаточно идти слева направо, поддерживать текущую префиксную сумму и сразу остановиться, как только она станет меньше нуля.
Если за весь проход этого не произошло, ответ -1.
2. Наблюдения
- Баланс после первых
iсобытий — это префиксная суммаa[1] + a[2] + ... + a[i]. - Требуется именно первая позиция, где эта сумма отрицательна.
- Поэтому нет смысла хранить все префиксные суммы: достаточно одной переменной
sum. - Как только
sum < 0, можно немедленно вывести текущую позицию, потому что более ранних отрицательных позиций уже не существует — мы просматриваем массив по порядку.
Пример:
a = [1, -1, -1, 1]- суммы по префиксам:
- после 1-го:
1 - после 2-го:
0 - после 3-го:
-1
- после 1-го:
- первая отрицательная сумма появилась на позиции
3.
3. Алгоритм
- Считать
n. - Завести переменную
sum = 0. - Для каждой позиции от
1доn:- считать очередное число
x; - прибавить его к
sum; - если
sum < 0, вывести текущую позицию и завершить программу.
- считать очередное число
- Если цикл закончился и отрицательной суммы не было, вывести
-1.
4. Почему это работает
Докажем, что алгоритм находит правильный ответ.
Во время прохода на шаге i переменная sum равна сумме первых i элементов, то есть текущему балансу после i событий. Это верно, потому что мы начинаем с 0 и каждый раз прибавляем очередное изменение.
Далее возможны два случая:
- Если на некоторой позиции
iвпервые выполняетсяsum < 0, то баланс после первыхiсобытий отрицателен, а на всех предыдущих позициях он не был отрицательным. Значит,iи есть искомый минимальный индекс. - Если после обработки всех
nэлементов ни разу не получилосьsum < 0, значит ни одна префиксная сумма не отрицательна. Тогда по условию нужно вывести-1.
Следовательно, алгоритм всегда выводит правильный ответ.
5. Сложность
- Время:
O(n), потому что массив просматривается один раз. - Память:
- в решении на C++:
O(1), так как элементы можно обрабатывать по одному; - в решении на Python ниже используется список из входных данных, поэтому
O(n).
- в решении на C++:
6. Код на C++17
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
long long sum = 0;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
sum += x;
if (sum < 0) {
cout << i << '\n';
return 0;
}
}
cout << -1 << '\n';
return 0;
}
7. Код на Python 3
n = int(input())
a = list(map(int, input().split()))
s = 0
for i in range(n):
s += a[i]
if s < 0:
print(i + 1)
break
else:
print(-1)
Комментарии