Перейти к содержанию
Educora
Средний9 класс25 мин33 / 59

Анализ программы: от результата к входным данным

Находим по трассировочной таблице, что напечатает программа, по напечатанному значению — число итераций, а превращая условие цикла в неравенства — наименьший и наибольший ввод и количество вводов с одинаковым результатом, как в закрытых и кодируемых заданиях ГЭЦ.

Проверь себя
В этом уроке ты узнаешь
  • строить трассировочную таблицу и находить, что напечатает программа
  • определять по напечатанному значению, сколько раз выполнился цикл
  • превращать условие цикла в два неравенства и находить наименьший и наибольший ввод и количество подходящих вводов
  • решать обратные задачи по цифрам, определять, какое выражение вычисляет цикл, и разбирать условия с функциями

В обычном задании даны программа и ввод, а результат находишь ты. ГЭЦ же часто спрашивает наоборот: «Если напечатано 77, каково наименьшее значение m?», «Сколько натуральных чисел можно ввести, чтобы каждый раз печаталось 9?». В каждом из четырёх вариантов 2025–2026 годов было хотя бы одно такое «обратное» задание, причём три из них были заданиями с кодируемым ответом, который записываешь сам. В этом уроке ты сначала освоишь трассировочную таблицу, а затем четырёхшаговый способ рассуждать от результата к вводу. Правила циклов — в уроках «Операторы цикла: for, while, шаг цикла, break, continue и вложенные циклы» и «Операции над числами: цифры, делители и простые числа».

Трассировочная таблица: что напечатает программа?

Определение
Трассировочная таблица

Таблица, показывающая выполнение программы шаг за шагом: каждый столбец — переменная (и условие цикла), а каждая строка — одна итерация.

Определение
Обратная задача

Даны программа и её результат, а искать нужно входное значение (наименьшее, наибольшее или количество подходящих значений).

В цикле while условие проверяется до тела: как только оно ложно, цикл заканчивается и программа переходит к строке после цикла. Поэтому после цикла переменные сохраняют значения последней итерации.

  1. 1
    Подготовь столбцы

    все переменные, которые меняются в цикле, и столбец «да/нет» для условия.

  2. 2
    Запиши начальные значения

    присваивания до цикла записываются в первую строку.

  3. 3
    Проверь условие

    «да» — выполни тело построчно сверху вниз и начни новую строку; «нет» — остановись.

  4. 4
    Посмотри на print

    печатаемое выражение может не совпадать с переменной (n + k, m * 10 + k); print(a, b) выводит два значения через пробел.

Python
s = 0
k = 1
while s < 40:
    if k % 2 == 0:
        s = s + k * k
    else:
        s = s + k
    k = k + 1
print(k, s)
▸ Ожидаемый результат
7 65
Программа к примеру 1: сначала построй таблицу, потом запусти и проверь.
Пример 1. Результат программы

Определите результат программы выше.
A) 6 65 B) 7 65 C) 7 29 D) 6 29 E) 8 65

Показать решение
k | s < 40? | s
1 | да | 0 + 1 = 1
2 | да | 1 + 2 · 2 = 5
3 | да | 5 + 3 = 8
4 | да | 8 + 4 · 4 = 24
5 | да | 24 + 5 = 29
6 | да (29 < 40) | 29 + 6 · 6 = 65
7 | нет (65 < 40 ложно) — цикл закончен.
Печатается: 7 65. Ответ: B. Ловушка: после цикла k уже равно 7, а не 6.

Сколько раз выполнился цикл? От результата к числу итераций

Первый шаг обратной задачи всегда одинаков. Если печатаемая переменная на каждой итерации меняется по одному правилу (прибавляется одно и то же число или она умножается на одно и то же число), по её итоговому значению находим число итераций k. Ввод на этом шаге ещё не нужен.

n = n₀ + k · d s = s₀ · qᵏ
где:
  • n₀, s₀значения до цикла
  • dчисло, прибавляемое на каждом шаге (n = n + d)
  • qчисло, на которое умножают на каждом шаге (s = s * q)
  • kчисло итераций

Сложение даёт арифметическую прогрессию, умножение — геометрическую.

Пример 2. Число итераций

Сколько раз выполнился цикл?
1) До цикла n = 5, в теле n = n + 6, после цикла напечатано 125.
2) s = 1, в теле s = s * 3, напечатано 243.
3) n = 2, в теле n = n * 4, напечатано 2048.
4) Счётчик k = 1, в теле k = k + 1, после цикла напечатано 8.

Показать решение
1) 5 + 6k = 125 → 6k = 120 → k = 20.
2) 3ᵏ = 243 = 3⁵ → k = 5.
3) 2 · 4ᵏ = 2048 → 4ᵏ = 1024 = 4⁵ → k = 5.
4) 1 + k = 8 → k = 7. Если счётчик начинается с 1, напечатанное значение на 1 больше числа итераций.

От условия к неравенствам: наименьший и наибольший ввод

Если цикл выполнился ровно k раз, верны два факта: после (k − 1)-й итерации условие ещё было истинным (иначе k-я итерация не началась бы), а после k-й стало ложным (цикл остановился). Эти два предложения дают два неравенства для ввода.

усл(x₍ₖ₋₁₎) — истинно, усл(xₖ) — ложно
где:
  • xₖзначение переменной цикла после k итераций, выраженное через ввод (например, s₀ + k · m)

Условие того, что цикл выполнится ровно k раз.

  1. 1
    Найди k

    число итераций по напечатанному значению.

  2. 2
    Вырази переменную через ввод

    например, после k шагов s = 25 + k · m.

  3. 3
    Составь два неравенства

    после k шагов условие ложно, после k − 1 шагов — истинно.

  4. 4
    Выбери целые решения

    наименьшее или наибольшее натуральное значение; количество всех подходящих вводов — R − L + 1.

Python
m = int(input())
n = 2
s = 25
while s <= 900:
    s = s + m
    n = n + 5
print(n)
Программа к примеру 3 — как на экзамене, читает с клавиатуры.
Пример 3. Наименьший ввод

Какое наименьшее натуральное значение m нужно ввести, чтобы программа напечатала 77? Каково наибольшее подходящее m?
A) 58 B) 59 C) 60 D) 62 E) 63

Показать решение
1) n = 2 + 5k = 77 → k = 15.
2) После k шагов s = 25 + k · m.
3) После 15 шагов цикл остановился: 25 + 15m > 900 → 15m > 875 → m > 58,3. После 14 шагов условие ещё было истинным: 25 + 14m ≤ 900 → m ≤ 62,5.
4) 59 ≤ m ≤ 62. Наименьшее — 59 (ответ B), наибольшее — 62; 77 печатают 4 ввода.
Проверка: при m = 58 после 15 шагов s = 895 ≤ 900 — цикл выполнится в 16-й раз и напечатает 82.
x // q = y ⇔ q · y ≤ x ≤ q · y + q − 1
где:
  • qделитель (a = a // q)
  • yрезультат целочисленного деления

Шаг назад через целочисленное деление: наименьшее x = q · y, наибольшее x = q · y + q − 1.

Пример 4. Обратный шаг через целочисленное деление

При каких x 1) x // 3 = 5; 2) x // 10 = 42; 3) x // 2 = 7?

Показать решение
1) 3 · 5 = 15 ≤ x ≤ 17: x = 15, 16, 17.
2) 420 ≤ x ≤ 429 — 10 чисел.
3) 14 ≤ x ≤ 15.
Python
a = int(input())
n = 1
while a > 5:
    a = a // 3
    n = n * 2
print(n)
Программа к примеру 5 — как на экзамене, читает с клавиатуры.
Пример 5. Наибольший и наименьший ввод (кодируемый ответ)

Чтобы программа напечатала 8, найдите 1) наибольшее натуральное значение a; 2) наименьшее натуральное значение; 3) количество таких значений.

Показать решение
n = 2ᵏ = 8 → k = 3. Восстанавливаем значения от конца к началу (a₃ — значение после 3 шагов).
1) Цикл остановился: a₃ ≤ 5, наибольшее a₃ = 5. На каждом шаге наибольшее x = 3y + 2: a₂ = 17, a₁ = 53, a = 161. Условия выполняются: 161, 53, 17 > 5.
2) 3-я итерация состоялась: a₂ > 5, то есть a₂ ≥ 6 (6 // 3 = 2 ≤ 5 — цикл останавливается). Наименьшее x = 3y: a₁ = 18, a = 54.
3) 54 ≤ a ≤ 161: 161 − 54 + 1 = 108 значений. Если в кодируемом задании спросят «разность наибольшего и наименьшего значений», ответ 161 − 54 = 107.

Сколько вводов дают один и тот же результат?

Здесь находим и наименьший (L), и наибольший (R) ввод. Если подходят все целые числа между ними, ответ — R − L + 1 (оба конца считаются). Если прибавляемое в теле число меняется (s = s + k * 4), сумму за k шагов считаем как сумму арифметической прогрессии.

количество = R − L + 1 1 + 2 + … + k = k(k + 1) / 2количество = R − L + 1 1 + 2 + … + k = k(k + 1) / 2
где:
  • L, Rнаименьший и наибольший подходящий ввод
  • k(k + 1) / 2k(k + 1) / 2сумма первых k натуральных чисел

Количество целых чисел на отрезке и сумма с растущим шагом.

Python
s = int(input())
k = 1
while s < 300:
    s = s + k * 4
    k = k + 1
print(k)
Программа к примеру 6 — как на экзамене, читает с клавиатуры.
Пример 6. Сколько натуральных чисел дают 9?

Сколько натуральных чисел можно ввести с клавиатуры, чтобы каждый раз печаталось 9?
A) 31 B) 32 C) 33 D) 144 E) 30

Показать решение
k начинается с 1 и после цикла равно 9, значит, цикл выполнился 8 раз (при k = 1, 2, …, 8).
За 8 шагов прибавлено: 4 · (1 + 2 + … + 8) = 4 · 36 = 144; за 7 шагов: 4 · 28 = 112.
После 8 шагов цикл остановился: s + 144 ≥ 300 → s ≥ 156.
После 7 шагов условие было истинным: s + 112 < 300 → s < 188, то есть s ≤ 187.
156 ≤ s ≤ 187: 187 − 156 + 1 = 32. Ответ: B.
Python
for m in range(1, 101):
    n = 2
    s = 25
    while s <= 900:
        s = s + m
        n = n + 5
    if n == 77:
        print(m)
▸ Ожидаемый результат
59
60
61
62
Полная проверка: 77 печатается только при m = 59, 60, 61, 62.

Цифры, формулы и функции

Если программа разбирает число на цифры, результат сообщает две вещи: сколько цифр и один факт о них (сумма, произведение…). Чтобы построить наибольшее число, крупные цифры ставим слева; в наименьшем числе первая цифра не меньше 1, а остаток суммы набираем справа девятками.

Python
y = int(input())
m = 0
n = 0
while y > 0:
    m = m + 3
    n = n + y % 10
    y = y // 10
print(m, n)
Программа к примеру 7 — как на экзамене, читает с клавиатуры.
Пример 7. Обратная задача по цифрам (кодируемый ответ)

Программа напечатала 12 21. Найдите наибольшее и наименьшее натуральное число, которое могло быть введено для y.

Показать решение
m растёт на 3 для каждой цифры: 12 / 3 = 4 — число четырёхзначное. n — сумма цифр: 21.
Наибольшее: слева как можно большие цифры — 9, 9, затем 21 − 18 = 3, в конце 0: 9930.
Наименьшее: первая цифра 1, остальные 20 набираем справа: 9, 9, затем 2 — 1299.
Проверка: 9 + 9 + 3 + 0 = 21, 1 + 2 + 9 + 9 = 21. Если спросят разность: 9930 − 1299 = 8631.

В вопросе «Какое выражение вычисляет программа?» записываем в трассировочную таблицу первые 2–3 итерации и замечаем закономерность членов. Затем проверяем варианты при n = 1 и n = 2.

Python
n = int(input())
s = 0
p = 1
for i in range(1, n + 1):
    p = p * 2
    s = s + i / p
print(s)
Программа к примеру 8 — как на экзамене, читает с клавиатуры.
Пример 8. Какое выражение вычисляет цикл?

Значение какого выражения вычисляет программа?
A) 1/2 + 1/4 + … + 1/2ⁿ
B) 1/2 + 2/4 + 3/8 + … + n/2ⁿ
C) 1/2 + 2/3 + … + n/(n + 1)
D) 2 + 4/2 + 8/3 + … + 2ⁿ/n
E) 1 + 1/2 + … + 1/n

Показать решение
i = 1: p = 2, s = 1/2
i = 2: p = 4, s = 1/2 + 2/4
i = 3: p = 8, s = 1/2 + 2/4 + 3/8
На каждом шаге p = 2ⁱ, а в числителе стоит i: член равен i/2ⁱ. Ответ: B.
Проверка: при n = 3 программа печатает 1.375, и 0,5 + 0,5 + 0,375 = 1,375.

В условии цикла может стоять функция (см. «Функция: def, параметры и return»). Сначала выпиши, какое выражение возвращает функция, а затем решай условие как обычное неравенство.

Python
def f(x):
    return x * x

def g(x):
    return 5 * x + 6

k = abs(int(input()))
i = 1
while f(i) <= g(k):
    i = i + 1
print(i)
Программа к примеру 9 — как на экзамене, читает с клавиатуры.
Пример 9. Функции в условии

1) С клавиатуры вводится −20. Что будет напечатано?
A) 10 B) 11 C) 12 D) 106 E) 9
2) При скольких натуральных k будет напечатано 11?

Показать решение
1) k = |−20| = 20, g(20) = 106. Цикл продолжается, пока i² ≤ 106: 10² = 100 ≤ 106, 11² = 121 > 106 — остановка. Печатается 11. Ответ: B.
2) Чтобы напечаталось 11, нужно 10² ≤ g(k) < 11², то есть 100 ≤ 5k + 6 ≤ 120 → 18,8 ≤ k ≤ 22,8 → k = 19, 20, 21, 22 — 4 числа.
Задание

Проверь пример 6: выполни его программу для каждого s = 1, 2, …, 400 и выведи в одной строке наименьшее s, дающее 9, наибольшее такое s и количество таких значений.

Задание · Python
lo = 0
hi = 0
c = 0
for x in range(1, 401):
    s = x
    k = 1
    # the loop of Example 6 here

    # if k == 9, update lo, hi and c

print(lo, hi, c)
▸ Ожидаемый результат
156 187 32
Задание

Проверь пример 7: среди y от 1000 до 9999 найди наибольшее число, для которого программа печатает 12 21, и выведи его.

Задание · Python
best = 0
for x in range(1000, 10000):
    y = x
    m = 0
    n = 0
    # the loop of Example 7 here

    # remember x if the program would print 12 21

print(best)
▸ Ожидаемый результат
9930

Главное

  • Условие while проверяется перед телом; после цикла переменные хранят значения последней итерации.
  • В обратной задаче сначала найди k: n = n₀ + k · d или s = s₀ · qᵏ.
  • Ровно k итераций: после k − 1 шагов условие истинно, после k шагов — ложно; это два неравенства.
  • Обратный шаг через целочисленное деление: x // q = y ⇔ q · y ≤ x ≤ q · y + q − 1; количество подходящих вводов — R − L + 1.
  • Для наибольшего числа крупные цифры ставь слева, для наименьшего девятки — справа; проверяй ответ вариантами или полным перебором.

Проверь себя

Вопросов: 12. Каждый правильный ответ приносит XP.

1 / 12
Когда проверяется условие цикла while?