Раздел 1 — Задача, модель, алгоритм

Как превратить условие задачи в модель и алгоритм, которые можно проверить до написания программы

Прогресс курса Раздел 1 из 20

Что вы освоите в этом разделе

6 академических часов: 3 часа теории, 3 часа практики. Компьютер в этом разделе не нужен. Модель и алгоритм, которые вы здесь научитесь строить, — основа каждой практической работы курса: с раздела 4 по ним будет писаться код.
01

От задачи к программе

Программа пишется не с первой строки кода. Между словами «надо посчитать, сколько краски купить» и работающей программой лежат этапы, и ошибка, пропущенная на раннем этапе, дорожает на каждом следующем.

ЭтапВопросРезультат
Постановка задачиЧто дано и что нужно получить?исходные данные, результат, ограничения
Математическая модельКак результат связан с исходными данными?величины, формулы, допущения
АлгоритмВ каком порядке считать?блок-схема или псевдокод
ПрограммаКак записать алгоритм на языке?исходный код
ТестированиеСовпадает ли результат с ожидаемым?набор тестовых примеров и их результаты

В этом разделе — первые три этапа. Программы по готовым алгоритмам начнутся в разделе 4, когда будут изучены основы языка C++. Требования к программе целиком, оформленные документом, — техническое задание — разбираются в разделе 13, когда за плечами будет достаточно написанных программ.

Типичная ошибка — сразу писать код «как понял». Если в условии не сказано, округлять ли результат и что делать с отрицательным вводом, это решение всё равно будет принято — но случайно, в момент набора строки кода, и никто его не проверит. Модель заставляет принять такие решения явно и записать их.
02

Постановка задачи

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

«Нужно покрасить стены прямоугольной комнаты. Известны размеры комнаты, площадь окон и дверей, расход краски на квадратный метр и объём банки. Стены красят в два слоя. Сколько банок купить?»

Разбор условия

  • Исходные данные: длина и ширина комнаты, высота стен, площадь проёмов, расход краски на 1 м² в один слой, число слоёв, объём банки.
  • Результат: число банок — целое, потому что банку не покупают частями.
  • Ограничения: размеры и расход больше нуля; площадь проёмов неотрицательна и меньше площади стен; число слоёв — целое, от 1.
  • Чего в условии нет: нужен ли запас краски; красят ли откосы окон; можно ли купить банки разного объёма. На эти вопросы отвечают допущения модели — пункт 04.

Ограничения — не формальность. Именно они определяют, что программа должна ответить на ввод «длина −5 м»: такая комната не существует, и честный ответ — сообщение об ошибке, а не отрицательное число банок.

Проверка постановки: для каждого исходного данного спросите «а если оно равно нулю? отрицательное? очень большое?». Если на вопрос нет ответа — ограничение ещё не записано.
03

Величины модели

Математическая модель — описание задачи на языке величин и формул. Она начинается с таблицы величин: у каждой есть обозначение, смысл, единица измерения, тип значения и допустимый диапазон.

ОбозначениеСмыслЕдиницаТипДопустимоРоль
a, bдлина и ширина комнатымвещественное> 0исходная
hвысота стенмвещественное> 0исходная
Sпрплощадь окон и дверейм²вещественное0 ≤ Sпр < 2(a+b)hисходная
rрасход краски на один слойл/м²вещественное> 0исходная
kчисло слоёвцелое≥ 1исходная
Vобъём банкилвещественное> 0исходная
Sстокрашиваемая площадьм²вещественное> 0промежуточная
Qнужный объём краскилвещественное> 0промежуточная
Nчисло банокшт.целое≥ 1результат

Тип «целое» или «вещественное» здесь — свойство величины в задаче, а не в языке программирования: число слоёв бывает только целым, длина — любой. В разделе 3 этой таблице будут соответствовать типы C++ int и double.

Единицы измерения — самый частый источник ошибок в модели. Если расход дан в мл/м², а банка в литрах, формула без перевода единиц даст ответ, завышенный в 1000 раз. Правило: у каждой величины в таблице есть единица, и в каждой формуле единицы слева и справа совпадают.
04

Формулы и допущения

Связи между величинами записываются формулами — по одной на каждую промежуточную величину и результат.

Sст = 2 · (a + b) · h − Sпр          [м²]    площадь четырёх стен без проёмов
Q   = Sст · k · r · 1,1             [л]     1,1 — запас 10 %
N   = ⌈ Q / V ⌉                    [шт.]   ⌈x⌉ — округление вверх до целого

Проверка единиц: м · м = м²; м² · л/м² = л; л / л — безразмерное число. Совпадает.

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

Допущения этой модели

  • Комната — прямоугольный параллелепипед, стены одной высоты.
  • Откосы окон и дверей не красят.
  • Запас на потери — 10 % от расчётного объёма.
  • Покупаются банки одного объёма; остаток краски допустим.

Модель проверяют контрольным примером — расчётом вручную на конкретных числах:

a = 5 м, b = 4 м, h = 2,7 м, Sпр = 3,5 м², r = 0,12 л/м², k = 2, V = 2,5 л

Sст = 2 · (5 + 4) · 2,7 − 3,5 = 48,6 − 3,5 = 45,1 м²
Q   = 45,1 · 2 · 0,12 · 1,1   = 11,9064 л
N   = ⌈ 11,9064 / 2,5 ⌉ = ⌈ 4,76 ⌉ = 5 банок
Обычное округление здесь — ошибка. При Q / V = 4,2 оно даст 4 банки, и краски не хватит на последнюю стену. Выбор округления — вверх, вниз или к ближайшему — определяется смыслом величины, и его обязательно записывают в модели. Для «сколько купить» — вверх, для «сколько целых полос выйдет из рулона» — вниз.
05

Модели с условием и с повторением

Не каждую задачу описывает одна формула. Встречаются ещё два вида моделей — они потом станут ветвлениями и циклами программы.

Кусочная модель: формула зависит от условия

«Поездка на такси стоит 150 ₽ за посадку и 30 ₽ за километр. Каждый километр после десятого стоит 20 ₽. Сколько стоит поездка длиной d км?»
         ⎧ 150 + 30 · d,                   если 0 < d ≤ 10
C(d) =   ⎨
         ⎩ 150 + 30 · 10 + 20 · (d − 10),  если d > 10

Контрольные примеры:
  d = 7   →  C = 150 + 210             = 360 ₽
  d = 10  →  C = 150 + 300             = 450 ₽   (граница: обе формулы дают 450)
  d = 15  →  C = 150 + 300 + 20 · 5    = 550 ₽

На границе условий — здесь d = 10 — обе формулы должны давать одно значение, если в условии нет скачка цены. Проверка границы находит ошибки вида «< вместо ≤» ещё до программы.

Итерационная модель: результат получается повторением шага

«На вклад положили 100 000 ₽ под 12 % годовых с ежемесячной капитализацией. Через сколько месяцев сумма впервые достигнет 110 000 ₽?»
S0 = P                              P — начальная сумма, ₽
Si = Si−1 · (1 + p / 1200)          p — ставка, % годовых; 1200 = 12 мес. · 100 %
Найти наименьшее n, при котором Sn ≥ T   T — целевая сумма, ₽

Ограничения: P > 0, T > P, p > 0

Здесь нет формулы «n = …», которую можно сразу вычислить: результат получается повторением одного и того же шага, пока не выполнится условие. Ограничение p > 0 обязательно: при нулевой ставке сумма никогда не вырастет, и повторение не закончится.

У итерационной модели всегда два обязательных вопроса: что меняется на каждом шаге и почему повторение когда-нибудь закончится. Если на второй вопрос ответа нет при каких-то допустимых данных — это ограничение, которого не хватает в модели.
06

Алгоритм и его свойства

Алгоритм — конечная последовательность точных предписаний исполнителю, которая приводит от исходных данных к результату. Модель говорит, что связано с чем; алгоритм — в каком порядке действовать.

СвойствоСмыслНарушение
Дискретностьалгоритм состоит из отдельных шагов«посчитайте как-нибудь»
Определённостькаждый шаг понимается однозначно«округлите» — вверх или вниз?
Конечностьалгоритм завершается за конечное число шаговповторение при нулевой ставке вклада
Результативностьна любых допустимых данных получается результат или сообщение об ошибкенет ответа на ввод «длина −5»
Массовостьалгоритм решает класс задач, а не один вариантрасчёт работает только для комнаты 5 × 4

Способов записать алгоритм три: словами, блок-схемой и псевдокодом. Словесная запись удобна для обсуждения, но легко становится неоднозначной. Блок-схема наглядна для ветвлений и циклов. Псевдокод ближе всего к будущей программе.

Словесная запись алгоритма покраски:

1. Ввести a, b, h, Sпр, r, k, V.
2. Если хотя бы одно значение недопустимо — сообщить об ошибке и закончить.
3. Вычислить площадь стен Sст = 2 · (a + b) · h − Sпр.
4. Вычислить объём краски Q = Sст · k · r · 1,1.
5. Вычислить N = Q / V, округлив вверх до целого.
6. Вывести N.
07

Блок-схемы по ГОСТ 19.701-90

Символы блок-схем в России установлены стандартом ГОСТ 19.701-90 «Схемы алгоритмов, программ, данных и систем». Для алгоритмов курса нужны семь символов.

СимволФормаНазначениеВ схемах этой страницы
Терминаторпрямоугольник со скруглёнными концаминачало и конец( Начало )
Данныепараллелограммввод и вывод/ Ввод a /
Процесспрямоугольниквычисление, присваивание[ S = a · b ]
Решениеромб, один вход и два выхода «да» / «нет»проверка условия< a > 0 ? >
Подготовкашестиугольникзаголовок цикла со счётчикомраздел 5
Предопределённый процесспрямоугольник с двойными боковыми сторонамивызов подпрограммыраздел 7
Соединительокружность с меткойразрыв линии на другой странице

Правила построения: поток идёт сверху вниз и слева направо — в этих направлениях стрелки можно не рисовать; в остальных стрелка обязательна. У схемы один вход и один выход. Линии не пересекаются без необходимости. Текст в символе — короткий: формула или условие, а не абзац.

Схема алгоритма покраски — на странице символы нарисованы упрощённо, соответствие — в таблице выше:

                 ( Начало )
                     │
      / Ввод a, b, h, Sпр, r, k, V /
                     │
         < данные допустимы? >──── нет ─────┐
                     │ да                   │
   [ Sст = 2 · (a + b) · h − Sпр ]          │
                     │                      │
   [ Q = Sст · k · r · 1,1 ]                │
                     │                      │
   [ N = ⌈Q / V⌉ ]                / Вывод «ошибка во     /
                     │            /  входных данных»     /
               / Вывод N /                  │
                     │◄─────────────────────┘
                 ( Конец )

Любой алгоритм можно составить из трёх базовых структур — это утверждение доказано (теорема Бёма — Якопини, 1966). Схемы, построенные только из них, называют структурными.

  Следование           Ветвление                   Цикл с предусловием

  [ действие 1 ]       < условие? >─ нет ─┐        ┌──►< условие? >─ нет ─┐
        │                   │ да          │        │        │ да           │
  [ действие 2 ]       [ действие 1 ]  [ действие 2 ]      [ тело ]        │
        │                   │             │        └────────┘              │
                            ├◄────────────┘                    ┌◄──────────┘
                            │                                  │

Схема итерационной модели вклада — цикл с предусловием:

               ( Начало )
                   │
         / Ввод P, p, T /
                   │
     < P > 0, T > P, p > 0 ? >──── нет ──────┐
                   │ да                      │
          [ S = P;  n = 0 ]                  │
                   │                         │
     ┌──────►< S < T ? >── нет ──┐           │
     │             │ да          │    / Вывод «ошибка» /
     │   [ S = S · (1 + p/1200) ]│           │
     │             │             │           │
     │        [ n = n + 1 ]      │           │
     └─────────────┘             │           │
                          / Вывод n /        │
                                 │◄──────────┘
                             ( Конец )
Частые ошибки в блок-схемах: ромб с одним выходом или с тремя; ввод-вывод в прямоугольнике вместо параллелограмма; ветка ошибки, которая никуда не ведёт — у схемы появляется второй «конец» или обрыв; стрелка цикла, которая возвращается не к проверке условия, а в середину тела.
08

Псевдокод, трассировка, тестовые примеры

Псевдокод — запись алгоритма ключевыми словами на естественном языке. У него нет строгого стандарта; важно, чтобы запись была однозначной и последовательной. В курсе используется такая форма:

ВВОД P, p, T
ЕСЛИ P ≤ 0 ИЛИ T ≤ P ИЛИ p ≤ 0 ТО
    ВЫВОД «ошибка во входных данных»
ИНАЧЕ
    S ← P
    n ← 0
    ПОКА S < T ВЫПОЛНЯТЬ
        S ← S · (1 + p / 1200)
        n ← n + 1
    КОНЕЦ ПОКА
    ВЫВОД n
КОНЕЦ ЕСЛИ

Стрелка означает присваивание: «вычислить правую часть и записать в переменную слева». Запись n ← n + 1 — не уравнение, а действие: увеличить n на единицу.

Трассировка — выполнение алгоритма вручную с записью значений всех переменных после каждого шага. Трассировка на контрольном примере P = 100 000, p = 12, T = 110 000:

ШагnS, ₽S < T ?
начало0100 000,00да
11101 000,00да
22102 010,00да
33103 030,10да
да
99109 368,53да
1010110 462,21нет — выход

Результат: 10 месяцев. Проверка другим способом: 1,019 ≈ 1,0937 < 1,1, а 1,0110 ≈ 1,1046 ≥ 1,1 — совпадает.

Один контрольный пример не доказывает правильность алгоритма. Минимальный набор тестовых примеров для любой задачи курса — три вида:

ВидЧто проверяетПример для таксиОжидается
Обычныйосновная ветвьd = 15550 ₽
Граничныйзначение на границе условия или диапазонаd = 10450 ₽
Недопустимыйреакцию на данные вне ограниченийd = −3сообщение об ошибке
Ожидаемый результат теста записывается до выполнения алгоритма — из модели и ручного расчёта. Тест, ожидаемый ответ которого списан с результата программы, ничего не проверяет. Эти же тесты с раздела 4 будут проверять ваши программы на C++.

Ключевые выводы раздела

Запомните главное

  • Постановка задачи — это исходные данные, результат и ограничения; ограничения определяют реакцию на недопустимый ввод
  • У каждой величины модели есть обозначение, единица измерения, тип и допустимый диапазон
  • В каждой формуле единицы слева и справа совпадают
  • Допущения не устраняют, а записывают; способ округления — тоже допущение, и он следует из смысла величины
  • Кусочная модель станет ветвлением, итерационная — циклом; у итерационной обязательно доказано, что повторение закончится
  • Блок-схема строится символами ГОСТ 19.701-90 из следования, ветвления и цикла; у неё один вход и один выход
  • Трассировка проверяет алгоритм на контрольном примере до написания программы
  • Минимальный набор тестов — обычный, граничный и недопустимый; ожидаемый результат записывается заранее
Связи раздела. Опирается на школьную математику: формулы, проценты, округление. Нужен для: раздела 3 — типы величин станут типами C++; разделов 4–6 — кусочные модели станут ветвлениями, итерационные — циклами, тестовые примеры — проверкой программ; раздела 13 — техническое задание опирается на постановку задачи.
Практические работы — на учебном портале. Практические работы №1 и №2, критерии оценивания, сдача работ и оценки преподавателя — в курсе на portal.nevabit.ru. Учётную запись выдаёт преподаватель.
Обзор курса Практика на портале