📘 Тема 1.4. Необходимый материал#
Шпаргалка по циклам и перебору вариантов.
1. Что такое цикл#
Цикл — конструкция, которая повторяет один и тот же блок кода много раз: пока выполняется условие или для каждого элемента набора данных.
Зачем нужны циклы:
- Меньше кода. Вместо миллиона одинаковых строк — один цикл.
- Работа с последовательностями. Сумма, максимум, подсчёт — всё это делается в цикле.
- Перебор вариантов. Можно проверить все возможные пары, тройки, комбинации.
Термины:
| Термин | Значение |
|---|---|
| итерация | одно выполнение тела цикла |
| тело цикла | блок кода, который повторяется |
| счётчик | переменная, которая меняется на каждой итерации (i) |
| условие продолжения | логическое выражение, которое проверяется перед итерацией |
Заметка
В олимпиадных задачах цикл выполняется 10⁵–10⁶ раз — это нормально. А вот 10⁹ итераций программа будет считать секунды и не уложится в лимит времени.
2. Цикл со счётчиком for#
Используется, когда количество повторений известно.
for
Порядок работы:
- Инициализация — выполняется один раз перед циклом. Здесь создаётся счётчик:
int i = 0. - Условие — проверяется перед каждой итерацией. Истинно — тело выполняется, ложно — цикл завершается.
- Тело цикла — то, что повторяется.
- Шаг — выполняется после каждой итерации. Обычно
i++.
// числа от 1 до 5
for
cout << endl; // 1 2 3 4 5
Три частых варианта границ#
// обход n элементов: i = 0, 1, ..., n - 1 — ровно n итераций
for
// числа от 1 до n включительно — тоже n итераций
for
// обратный обход: n, n - 1, ..., 1
for
Предупреждение
i < nиi <= n— это разное число итераций. Дляfor (int i = 0; i < n; i++)итераций ровноn, а дляfor (int i = 0; i <= n; i++)— ужеn + 1. Это самая частая ошибка на олимпиадах.
3. Цикл с пред-условием while#
Используется, когда количество повторений заранее неизвестно, но есть условие продолжения.
while
Порядок работы: проверяется условие → если истинно, выполняется тело → условие проверяется снова → если ложно, цикл завершается.
// сумма чисел от 1 до n
int s = 0;
int i = 1;
while
Внимание
В
whileсчётчик меняется вручную внутри тела цикла. Если забытьi++, условие никогда не станет ложным и программа зависнет — получится бесконечный цикл.
4. Цикл с пост-условием do-while#
Похож на while, но условие проверяется после тела, поэтому тело выполняется хотя бы один раз.
do while ;
// сумма и количество чисел до первого нуля
double sum = 0;
int count = 0;
double number;
do while ;
Заметка
do-whileнужен там, где действие должно произойти хотя бы раз: например, «запросить пароль, потом проверить». В олимпиадных задачах он встречается редко, чаще хватаетwhile.
5. Какой цикл выбрать#
| Цикл | Когда использовать | Особенность |
|---|---|---|
for |
известно количество повторений | счётчик создаётся и изменяется в заголовке |
while |
количество повторений неизвестно, но есть условие | счётчик изменяется вручную |
do-while |
тело должно выполниться хотя бы один раз | условие проверяется после тела |
Правило выбора:
- знаете, сколько раз повторять —
for; - повторяете, пока что-то истинно —
while; - нужно выполнить тело хотя бы раз —
do-while.
6. Вложенные циклы и полный перебор#
Вложенный цикл — цикл внутри цикла. Внешний цикл делает одну итерацию, а внутренний за это время полностью проходит все свои.
// таблица умножения 3 × 3
for
1 2 3
2 4 6
3 6 9
Полный перебор — стратегия, при которой мы проверяем все возможные варианты и выбираем подходящий. Обычно реализуется вложенными циклами.
// все пары (i, j), такие что i + j = 5
for
Предупреждение
Два вложенных цикла по
nитераций даютn²операций — сложность O(n²). Дляn = 1000это миллион операций (быстро), а дляn = 100000— уже 10¹⁰ (слишком долго). Если перебор не укладывается в лимит времени, ищите формулу или другой алгоритм.
7. Шаблоны задач#
Сумма#
int sum = 0;
for
Сумма с условием#
int sum = 0;
for
Подсчёт количества#
int cnt = 0;
for
Максимум и минимум#
int mx = -1000000000; // «минус бесконечность»
int mn = 1000000000; // «плюс бесконечность»
for
Поиск первого подходящего#
for
cout << 0 << endl; // не нашли
Количество максимальных элементов#
int mx = -1000000000;
int cnt = 0;
for
Второй максимум#
int mx1 = -1000000000; // максимум
int mx2 = -1000000000; // наибольшее число, меньшее максимума
for
Длина самой длинной серии#
int current = 0, best = 0;
for
Важно
Переменные
sum,cnt,mx,mnобязательно инициализируются до цикла. Иначе там будет «мусор» и ответ окажется неверным.
8. Последовательность, которая заканчивается нулём#
Если количество чисел заранее неизвестно, а последовательность завершается нулём (ноль в неё не входит), удобно писать так:
int x;
while
Условие cin >> x && x != 0 читается так: «считать число, и если оно не ноль — продолжить». Как только встречается 0, цикл завершается.
// максимум последовательности до нуля
int mx = -1000000000;
int x;
while
cout << mx << endl;
9. Формула вместо цикла#
Сумму арифметической прогрессии можно посчитать без цикла:
1 + 2 + 3 + ... + n = n * (n + 1) / 2
// циклом — n итераций
int s = 0;
for
// формулой — одна операция
long long s = n * / 2;
Пример: задача «Ёлочки». Ёлка красоты n состоит из 2n ветвей длины 1, 2, ..., n и ствола длины 2n + 1. Площадь равна 2 * (1 + 2 + ... + n) + 2n + 1, то есть n * (n + 1) + 2n + 1.
long long n;
cin >> n;
cout << n * + 2 * n + 1 << endl;
Совет
Если задачу можно решить формулой — решайте формулой. Цикл на 2·10⁹ итераций работает десятки секунд и не проходит по времени, а формула — мгновенно.
И следите за типом: при
nдо 2·10⁹ произведениеn * (n + 1)достигает 4·10¹⁸ и вintне помещается — нуженlong long.
10. Типичные ошибки#
| ❌ Неправильно | ✅ Правильно |
|---|---|
for (int i = 0; i <= n; i++) для обхода n элементов |
for (int i = 0; i < n; i++) |
while (i <= n) { s += i; } — забыли i++ |
добавить i++ в тело цикла |
int sum; и сразу sum += x; |
int sum = 0; до цикла |
int mx = 0; для максимума отрицательных чисел |
int mx = -1000000000; или первый элемент |
if (x > mx) mx = x; для подсчёта максимумов |
if (x > mx) { mx = x; cnt = 1; } else if (x == mx) cnt++; |
int для сумм и произведений больше 2·10⁹ |
long long |
| Цикл на 10⁹ итераций там, где есть формула | посчитать формулой |
Вывод подсказок вроде Введите число: |
выводить только ответ |
11. Шаблон программы#
using namespace std;
int