Материалы для подготовки к ЕГЭ по информатике

реклама
Томский государственный университет
Факультет информатики
Ю. Л. Костюк, И. Л. Фукс
МАТЕРИАЛЫ ДЛЯ ПОДГОТОВКИ К ЕГЭ ПО ИНФОРМАТИКЕ
Методические указания
Томск – 2009
Методические указания предназначены для учащихся 11-х классов, собирающихся сдавать ЕГЭ по информатике с целью поступления
на физико-математические и технические факультеты университетов.
Материал базируется на демонстрационном варианте ЕГЭ 2009 года,
адрес
электронного
ресурса
–
http://www.fipi.ru/view/sections/197/docs/388.html.
Задания ЕГЭ сгруппированы по темам, каждая тема предваряется
кратким описанием соответствующего раздела теоретической части
школьного курса информатики. Для каждого задания приводится подробный разбор решения.
Почтовый адрес:
634050, г. Томск, пр. Ленина, 36, ТГУ,
приемная комиссия
Телефон:
(382-2) 52-96-72
http://www.tsu.ru
Информационный сайт ТГУ:
Электронная почта:
kostuk@inf.tsu.ru
fooxil@sibmail.com
© Костюк Ю. Л., Фукс И. Л., 2009
3
1. АЛГОРИТМЫ НА ЕСТЕСТВЕННОМ ЯЗЫКЕ
Для решения этих задач нужно уметь устанавливать причинноследственные связи между данными.
A10 (2 мин)
Между четырьмя местными аэропортами: ОКТЯБРЬ, БЕРЕГ,
КРАСНЫЙ и СОСНОВО, ежедневно выполняются авиарейсы. Приведён
фрагмент расписания перелётов между ними:
Аэропорт
вылета
СОСНОВО
КРАСНЫЙ
ОКТЯБРЬ
БЕРЕГ
СОСНОВО
КРАСНЫЙ
ОКТЯБРЬ
ОКТЯБРЬ
СОСНОВО
БЕРЕГ
Аэропорт прилета
КРАСНЫЙ
ОКТЯБРЬ
КРАСНЫЙ
СОСНОВО
ОКТЯБРЬ
СОСНОВО
СОСНОВО
БЕРЕГ
БЕРЕГ
ОКТЯБРЬ
Время вылета
Время прилета
06:20
10:25
11:45
12:15
12:45
13:15
13:40
15:30
17:35
19:40
08:35
12:35
13:30
14:25
16:35
15:40
17:25
17:15
19:30
21:55
Путешественник оказался в аэропорту ОКТЯБРЬ в полночь (0:00).
Определите самое раннее время, когда он может попасть в аэропорт
СОСНОВО.
1) 15:40
2) 16:35
3) 17:15
4) 17:25
РЕШЕНИЕ
При составлении маршрута следует иметь в виду, что из одного аэропорта можно попасть в другой как прямым рейсом, так и с пересадкой.
Рассмотрим два варианта решения задачи.
Решение А: от времени вылета ко времени прибытия.
В соответствии с расписанием из ОКТЯБРЬ можно вылететь в 11:45,
13:40 или 15:30.
4
Рейс до КРАСНЫЙ прибывает в 13:30, а вылет из КРАСНЫЙ в
СОСНОВО – в 13:15. Вывод 1: полет с пересадкой завершится на следующий день.
Прямой рейс из ОКТЯБРЬ в СОСНОВО прибывает в 17:25.
Рейс до БЕРЕГ прибывает в 17:15, а вылет из БЕРЕГ в СОСНОВО – в
12:15. Вывод 2: полет с пересадкой завершится на следующий день. Окончательный вывод: лететь прямым рейсом. Ответ: 4.
Решение Б: от времени прибытия ко времени вылета.
В соответствии с расписанием в СОСНОВО можно попасть в 14:25,
15:40 или 17:25. Вывод 1: ответы 2 и 3 неверны. Вывод 2: лететь через
БЕРЕГ нельзя. Остаются два пути: прямым рейсом или с пересадкой в
КРАСНЫЙ.
Рейс из ОКТЯБРЬ в КРАСНЫЙ прибывает в 13:30, улететь из
КРАСНЫЙ в СОСНОВО можно в 13:15. Вывод 3: полет с пересадкой завершится на следующий день.
Прямой рейс из ОКТЯБРЬ в СОСНОВО прибывает в 17:25. Окончательный вывод: лететь прямым рейсом. Ответ: 4.
A12 (2 мин)
Цепочка из трех бусин, помеченных латинскими буквами, формируется по следующему правилу. В конце цепочки стоит одна из бусин A, B, C.
На первом месте – одна из бусин B, D, C, которой нет на третьем месте. В
середине – одна из бусин А, C, E, B, не стоящая на первом месте.
Какая из перечисленных цепочек создана по этому правилу?
1) CBB
2) EAC
3) BCD
4) BCB
РЕШЕНИЕ
Последовательно проверяем выполнение каждого правила для каждой
цепочки, отсеивая неправильные ответы.
В цепочке 3) не выполняется правило о последней бусине.
В цепочке 2) не выполняется правило о первой бусине.
В цепочке 4) не выполняется правило о первой бусине, которой не
должно быть на третьем месте.
Верный ответ найден. Заметим, что правило о средней бусине не пригодилось. Однако все правила для цепочки 1) следует проверить и убедиться, что она создана верно. Ответ: 1.
5
B8 (10 мин)
Строки (цепочки символов латинских букв) создаются по следующему
правилу.
Первая строка состоит из одного символа – латинской буквы «А».
Каждая из последующих цепочек создается такими действиями: в очередную строку сначала записывается буква, чей порядковый номер в алфавите
соответствует номеру строки (на i-м шаге пишется i-я буква алфавита), к
ней справа дважды подряд приписывается предыдущая строка.
Вот первые 4 строки, созданные по этому правилу:
(1) A
(2) BAA
(3) CBAABAA
(4) DCBAABAACBAABAA
Латинский алфавит (для справки):
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Запишите семь символов подряд, стоящие в восьмой строке со 126-го
по 132-е место (считая слева направо).
РЕШЕНИЕ
Подсчитаем последовательно длины цепочек для того, чтобы определить, в каком месте появляются нужные нам символы. Длина каждой следующей цепочки равна удвоенной длине предыдущей цепочки +1.
(1) A
(2) BAA
(3) CBAABAA
(4) DCBAABAACBAABAA
(5) E(4)(4)
(6) F(5)(5)
(7) G(6)(6)
(8) H(7)(7)
1
3
7
15
31
63
127 – последовательность нужных
символов начинается в конце этой
цепочки.
За счет символа H номера символов
первой цепочки (7) увеличились на 1.
Следовательно, последний символ
цепочки (7) попал на 128-е место.
6
Значит, последовательность нужных
символов начинается с 3-х последних
символов цепочки (7): BAA. Остальные 4 символа – первые в цепочке (7):
GFED.
Ответ: BAAGFED
7
2. ОСНОВЫ ЛОГИКИ
Математическая логика – одна из базовых математических дисциплин
информатики. Элементарными объектами в логике являются высказывания, например: «Луна – спутник Земли», «6 < 3», «6 > 3». Значением (величиной) конкретного высказывания может быть истина или ложь. Приведенные примеры высказываний являются константами, их значения неизменны.
Высказывание может зависеть от чего-либо, тогда его значение иногда
может быть истинным, а иногда – ложным, например: «Сегодня солнечная
погода», «x >7». Первое высказывание зависит от погоды в момент его
чтения, а второе – от текущего значения переменной x.
Для логических данных используют специальные операции, которые
тоже называются логическими. В выражениях эти операции могут обозначаться разными способами.
Название операции
Альтернативные названия
Знаки
Конъюнкция
Логическое умножение,
Логическое И
Λ &
and
Дизъюнкция
Логическое сложение,
Логическое ИЛИ
V |
or
Отрицание
Инверсия
Следование
Эквивалентность
Исключающее ИЛИ
Импликация
¬
not
→
=

xor
Примеры
AΛB
A&B
A and B
AVB
A|B
A or B
¬A
A
not A
A →B
A=B
A B
A xor B
Логические операции удобно определять с помощью таблиц истинности, в которых для конкретных значений аргументов приводятся значения
выражений.
8
Таблицы истинности для указанных логических операций:
A
0
0
1
1
B
0
1
0
1
AΛB
0
0
0
1
AVB
0
1
1
1
¬A
1
1
0
0
A →B
1
1
0
1
A=B
1
0
0
1
A B
0
1
1
0
Три операции – конъюнкция, дизъюнкция и отрицание – являются базовыми. Все остальные операции могут быть выражены через базовые.
Например,
a  b = (a V b) Λ (¬a V ¬b);
исключающее ИЛИ:
следование:
a → b = (¬a V b);
эквивалентность:
(a = b) = ( a Λ b) V (¬a Λ ¬b).
Частью математической логики является булева алгебра, в которой выведены законы преобразования логических выражений.
1. Выражения с константами:
0 V A = A, 1 V A = 1, 0 Λ A = 0, 1 Λ A = A.
2. Выражения с одной переменной:
A V A = A, A Λ A = A, A V ¬ A = 1, A Λ ¬ A = 0.
3. Выражения со скобками и одинаковыми операциями (ассоциативность):
(A Λ B) Λ C = A Λ (B Λ C), (A V B) V C = A V (B V C).
4. Выражения со скобками и разными операциями (дистрибутивность):
A Λ (B V C) = (A Λ B) V (A Λ C), A V (B Λ C) = (A V B) Λ (A V C).
5. Перестановка операндов в выражениях (коммутативность):
A Λ B = B Λ A, A V B = B V A.
6. Выражения с операцией отрицания (законы де Моргана):
¬(A Λ B) = ¬A V ¬B, ¬(A V B) = ¬A Λ ¬B.
7. Двойное отрицание (закон отрицания отрицания):
¬¬A = ¬(¬A) = A.
9
A7 (3 мин)
Для какого из указанных значений X истинно высказывание
¬ ((X>2) → (X>3))?
1) 1
2) 2
3) 3
4) 4
РЕШЕНИЕ
Введем обозначения: A = X>2; B = X>3. Тогда высказывание примет
вид ¬ (A → B). Составим для этого высказывания таблицу истинности:
A
0
0
1
1
B
0
1
0
1
A→B
1
1
0
1
¬ (A → B)
0
0
1
0
Высказывание истинно, если A истинно, а B ложно, т.е. 2<X<=3. Следовательно, ответ: 3.
A8 (1 мин)
Укажите, какое логическое выражение равносильно выражению
A /\ ¬ (¬B \/ C).
1) ¬A \/ ¬B \/ ¬C
2) A /\ ¬B /\ ¬C
3) A /\ B /\ ¬C
4) A /\ ¬B /\ C
РЕШЕНИЕ
Преобразуем исходное выражение, раскрывая скобки:
A /\ ¬ (¬B \/ C) = { закон де Моргана ¬(A V B) = ¬A Λ ¬B}
A /\ (¬¬B Λ ¬C) = {двойное отрицание ¬¬A = A}
A /\ (B Λ ¬C).
Отсюда видно, что ответ: 3.
Замечание. Подобные задачи можно решать, составляя таблицы истинности для заданных выражений и сравнивая соответствующие столбцы друг с
другом.
10
A9 (2 мин)
Символом F обозначено одно из указанных ниже логических выражений от трех аргументов: X, Y, Z.
Дан фрагмент таблицы истинности выражения F:
X
1
0
1
Y
0
0
1
Z
0
0
1
F
1
1
0
Какое выражение соответствует F?
1) ¬X /\ ¬Y /\ ¬Z
2) X /\ Y /\ Z
3) X \/ Y \/ Z
4) ¬X \/ ¬Y \/ ¬Z
РЕШЕНИЕ
Поскольку в ответах присутствуют выражения с операцией конъюнкции, удобнее начать проверку именно с них.
Ответ 1): выражение будет истинным, если все операнды ложны. Это
соответствует второй строке таблицы истинности, но не подходит для первой строки.
Ответ 2): выражение будет истинным, если все операнды истинны. Это
не соответствует никакой строке таблицы.
Ответ 3): выражение будет истинным, если хотя бы один операнд истинен. Это соответствует только третьей строке таблицы.
Ответ 4): выражение будет истинным, если хотя бы один операнд ложен. Это полностью соответствует таблице.
Ответ: 4.
B4 (10 мин)
Каково наибольшее целое число X, при котором истинно высказывание
(50 < X·X) → (50 > (X+1) ∙ (X+1))?
11
РЕШЕНИЕ
Введем обозначения: A = 50 < X·X; B = 50 > (X+1) ∙ (X+1). Тогда высказывание примет вид A → B. Составим для этого высказывания таблицу
истинности:
A
0
0
1
1
B
0
1
0
1
A→B
1
1
0
1
Высказывание истинно, если A и B оба истинны или оба ложны, либо
A ложно, а B истинно.
Допустим, что A и B истинны. Это означает, что 50 < X·X, т.е. X >= 8,
и 50 > (X+1) ∙ (X+1), т.е. (X+1) <= 7, X <= 6. Условия несовместны.
Допустим, что A и B ложны. Это означает, что 50 >= X·X, т.е. X <= 7, и
50 <= (X+1) ∙ (X+1), т.е. (X+1) > 7, X > 6. Совместное условие 7 >= X > 6.
Отсюда выводится возможный ответ X = 7.
Допустим, что A ложно, а B истинно. Это означает, что 50 >= X·X, т.е.
X <= 7, и 50 > (X+1) ∙ (X+1), т.е. (X+1) <= 7, X <= 6. Совместное условие
X <= 6, т.е. возможный ответ X – любое целое не больше 6.
Поскольку требуется найти наибольшее X, то ответ: 7
B6 (8 мин)
Классный руководитель пожаловался директору, что у него в классе
появилась компания из 3-х учеников, один из которых всегда говорит
правду, другой всегда лжет, а третий говорит через раз то ложь, то правду.
Директор знает, что их зовут Коля, Саша и Миша, но не знает, кто из них
правдив, а кто – нет. Однажды все трое прогуляли урок астрономии. Директор знает, что никогда раньше никто из них не прогуливал астрономию.
Он вызвал всех троих в кабинет и поговорил с мальчиками. Коля сказал:
"Я всегда прогуливаю астрономию. Не верьте тому, что скажет Саша".
Саша сказал: "Это был мой первый прогул этого предмета". Миша сказал:
"Все, что говорит Коля, – правда". Директор понял, кто из них кто. Расположите первые буквы имен мальчиков в порядке: "говорит всегда правду",
"всегда лжет", "говорит правду через раз". (Пример: если бы имена мальчиков были Рома, Толя и Вася, ответ мог бы быть: РТВ).
12
РЕШЕНИЕ
Ответы мальчиков являются высказываниями. Для решения подобных
задач удобно использовать таблицу, в клетках которой отображены значения этих высказываний.
Будем заносить в клетку таблицы «1», если высказывание истинно, и
«0», если высказывание ложно. Первый ответ Коли не может быть правдивым, поскольку астрономию он раньше не прогуливал. По этой же причине
Сашин ответ правдив.
Коля 1
0
Коля 2
Саша
1
Миша
Второй ответ Коли ложный, потому что Саша сказал правду.
Коля 1
0
Коля 2
0
Саша
1
Миша
Итак, Коля солгал 2 раза, значит ответ Миши ложный.
Коля 1
0
Коля 2
0
Саша
1
Миша
0
Теперь можно сделать окончательный вывод о правдивости мальчиков:
Саша всегда говорит правду, Коля всегда лжет, значит, Миша говорит
правду через раз.
Ответ: СКМ
Рассмотрим еще одну подобную задачу.
Три школьника, остававшиеся в классе на перемене, были вызваны к
директору по поводу разбитого в это время окна. На вопрос директора, кто
и как разбил окно в классе, мальчики ответили следующее:
Андрей: «Олег бросил в меня портфелем, а попал в окно…»
Олег: «Сергей разбил футбольным мячом»
Сергей: «Разбил Андрей, и никакого мяча не было!»
Стало известно, что, желая запутать взрослых, каждый из ребят ровно
один раз сказал правду, а один раз – нет. Кто и чем разбил стекло в классе?
РЕШЕНИЕ
Создадим таблицу для отображения значений высказываний.
Андрей
Олег
Сергей
Мяч
Портфель
13
Андрей
Олег
Сергей
Каждая строка таблицы – значения высказываний отдельного человека.
Каждый столбец таблицы выделен для обозначения человека или предмета, о котором говорится в высказывании.
Начинаем заполнять таблицу. Допустим, в высказывании Андрея верно
то, что Олег разбил окно. Тогда он разбил окно не портфелем.
Андрей
Андрей
Олег
Сергей
Олег
1
Сергей
Мяч
Портфель
0
В высказывании Олега не может быть верным указание на Сергея, потому что в таблице отмечено, что разбил Олег. Следовательно, Олег прав в
том, что окно разбито мячом.
Андрей
Андрей
Олег
Сергей
Олег
1
Сергей
Мяч
0
1
Портфель
0
В высказывании Сергея не может быть верным указание на Андрея,
потому что в таблице отмечено, что разбил Олег. Следовательно, Сергей
прав в том, что окно разбито не мячом.
Андрей
Андрей
Олег
Сергей
Олег
1
Сергей
Мяч
0
1
0
0
Портфель
0
Получилось противоречие, значит, первые предположения о высказываниях Андрея были неверны.
Заполняем таблицу по-другому. Допустим, в высказывании Андрея неверно то, что Олег разбил окно. Тогда окно разбито портфелем.
Андрей
Андрей
Олег
Олег
0
Сергей
Мяч
Портфель
1
14
Сергей
Предположим, что в высказывании Олега верно указание на Сергея,
тогда Олег не прав в том, что окно разбито мячом.
Андрей
Андрей
Олег
Сергей
Олег
0
Сергей
Мяч
1
0
Портфель
1
В высказывании Сергея не может быть верным указание на Андрея, потому что в таблице отмечено, что разбил Сергей. Следовательно, Сергей прав
в том, что окно разбито не мячом.
Андрей
Андрей
Олег
Сергей
0
Олег
0
Сергей
Мяч
1
0
0
Видно, что окно разбил Сергей, попав в него портфелем.
Портфель
1
15
3. СИСТЕМЫ СЧИСЛЕНИЯ
Система счисления задает правила записи чисел. Из истории известно
много примеров использования разных систем счисления или нумерации.
Все виды нумерации можно разделить на две группы: непозиционные и
позиционные. В позиционной системе вклад каждой цифры в число зависит от позиции (разряда), в которой эта цифра находится. Количество разных цифр, которые можно использовать для записи чисел в позиционной
системе, называется основанием системы счисления.
Величину любого числа, заданного в позиционной системе счисления с основанием p, можно представить в виде полинома относительно p
S ( p)  a n p n  a n 1 p n 1  a n  2 p n  2    a1 p 1  a 0 p 0 ,
i  0, n – отдельные цифры заданного числа, для которых выполняется условие 0  ai  p. Если p  10 , то для записи можно исгде ai ,
пользовать десятичные цифры. Например, 3415  3 * 5  4 * 5  1. При
возрастании p приходится добавлять специальные знаки, обозначающие
2
величины больше 9: 5 A916  5 * 16  A * 16  9.
Перевод чисел из системы с основанием p в систему с основанием
10. Если вычислить значение полинома по правилам десятичной арифметики, то получится величина того же числа в десятичной системе счисления.
Например, 3415 = 3*52 + 4*5 +1 = 3*25 + 20 + 1 = 9610;
5А916 = 5*162 + А*16 + 9 = 5*256 + 10*16 + 9 = 1449.
Полином можно преобразовать, используя формулу Горнера:
2
S ( p)  ((( an p  an1 ) p  an2 ) p    a1 ) p  a0 .
Такое представление полинома удобно использовать для составления
алгоритма перевода числа из заданной системы счисления в десятичную.
Перевод чисел из системы с основанием 10 в систему с основанием
q. Пусть T(10) – значение числа в десятичной системе счисления. Эту величину можно представить в системе с основанием q в виде полинома,
преобразованного по формуле Горнера:
T(10) = (∙∙∙((bm q + bm-1) q + bm-2) q + ∙∙∙ +b1) q + b0,
16
где bi , i  0, m – цифры числа в системе с основанием q. Задача перевода заключается в вычислении этих цифр.
Из записи полинома видно, что младшая из искомых цифр может быть
вычислена как остаток от целочисленного деления заданного числа на основание q, поскольку это число и искомые цифры являются целочисленными величинами. В то же время частное от этого деления – коэффициент
перед q, заключенный во внешние скобки. Вычислив остаток от целочисленного деления частного на q, получаем следующую цифру числа и т.д.
Вычисления продолжаются до тех пор, пока очередное частное не станет
равно 0.
Например, перевод числа 9610 в систему с основанием 5:
96 | 5
5
19 | 5
46 15 3
45
4
1 (младшая цифра)
Простой способ перевода чисел из системы с основанием 10 в систему с основанием 2. Идея этого способа заключается в использовании
весов двоичных разрядов, выраженных в десятичной системе счисления.
Вес разряда равен основанию системы счисления, т.е. 2, возведенному в
степень, равную номеру разряда. Заполним вспомогательную таблицу:
Номер
разряда
8
7
6
5
4
3
2
1
0
Вес
разряда
256
128
64
32
16
8
4
2
1
Допустим, требуется перевести некоторое десятичное число в двоичную систему. Находим в таблице наибольший вес, значение которого
меньше или равно заданному числу. В соответствующий разряд двоичного
числа помещаем 1. Вычитаем из исходного числа выбранный вес, для разности повторяем те же действия. И так до тех пор, пока очередное значение разности не станет равно 0. В незаполненные единицами разряды двоичного представления записываем 0. Перевод завершен.
Например, перевести 34510 в двоичную систему счисления. Первый
подходящий вес – 256. В 8-й разряд записываем 1, вычисляем разность 345
– 256 = 89. Следующий подходящий вес – 64. В 6-й разряд – 1, разность 25.
17
Далее вес – 16, разряд – 4, разность – 9. Следующий вес – 8, разряд – 3,
разность – 1. Последний вес – 1, разряд – 0, разность – 0.
Номер разряда
Вес разряда
Заполнение
ницами
еди-
Двоичное число
8
7
6
5
4
3
2
1
0
256
128
64
32
16
8
4
2
1
1
1
1
1
1
1
1
0
1
0
1
0
0
1
счисления
с
основаниями,
равными
2 , где d  2  целое . Целые положительные числа хранятся в памяти компьютера в двоичном формате, полностью совпадающим с представлением числа в двоичной системе счисления. Для перевода числа из
d
двоичной системы в систему с основанием 2 достаточно разбить последовательность двоичных разрядов на группы по d двоичных цифр и обозначить каждую группу соответствующей цифрой новой системы счисления. Разбиение производится в направлении от младших разрядов к старd
шим. Перевод из системы с основанием 2 в двоичную заключается в последовательной записи групп двоичных разрядов для каждой 16-ричной
цифры. Ниже приведена таблица соответствия для 8- и 16-ричной систем
счисления:
d
Системы
Группа двоичных
разрядов
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
8-ричная цифра
(число)
0
1
2
3
4
5
6
7
10
11
12
13
16-ричная
цифра
0
1
2
3
4
5
6
7
8
9
A
B
Десятичное
число
0
1
2
3
4
5
6
7
8
9
10
11
18
1100
1101
1110
1111
14
15
16
17
C
D
E
F
12
13
14
15
Пример 1. Пусть задано число 011100101000100100 2 . Его нужно
перевести в систему с основанием 16  2 . Разобьем последовательность
двоичных разрядов на группы по 4 и обозначим каждую группу соответствующей цифрой 16-ричной системы счисления:
4
01 1100 1010 0010 0100
1
C
A
2
4
Получили 011100101000100100 2  1CA2416 .
Пример 2. Число 365708 перевести в двоичную систему счисления. Поскольку 8 = 23, для каждой цифры исходного числа запишем соответствующую последовательность из трех двоичных цифр:
3
011
6
110
5
101
7
111
0
000
Получили 365708 = 111101011110002, 0 в старшем разряде является
незначащим.
A3 (1 мин)
Дано: а=D716, b=3318. Какое из чисел c, записанных в двоичной системе, отвечает условию a<c<b?
1) 11011001
2) 11011100
3) 11010111
4) 11011000
РЕШЕНИЕ
1. Заданные числа перевести в двоичную систему. Каждую цифру числа a заменить последовательностью из 4-х двоичных цифр, для цифр числа
b – по 3 двоичные цифры:
a = 11010111;
b = 011011001 = 11011001.
2. Количество цифр во всех числах одинаково, следовательно, нужно
сравнивать сами цифры от старших разрядов к младшим.
a
1)
b
1
1
1
1
1
1
0
0
0
1
1
1
0
1
1
1
0
0
1
0
0
1
1
1
Больше a, но равно b
19
a
2)
b
1
1
1
1
1
1
0
0
0
1
1
1
0
1
1
1
1
0
1
0
0
1
0
1
Больше a и b
a
3)
b
1
1
1
1
1
1
0
0
0
1
1
1
0
0
1
1
1
0
1
1
0
1
1
1
Меньше b, но равно a
a
4)
b
1
1
1
1
1
1
0
0
0
1
1
1
0
1
1
1
0
0
1
0
0
1
0
1
Ответ: 4.
A4 (2 мин)
Чему равна сумма чисел 438 и 5616?
1) 1218
2) 1718
3) 6916
4) 10000012
РЕШЕНИЕ
1. Заданные числа перевести в двоичную систему. Каждую цифру
восьмеричного числа заменить последовательностью из 3-х двоичных
цифр, для цифр шестнадцатеричного числа – по 4 двоичные цифры:
438 = 1000112;
5616 = 010101102 = 10101102;
1218 = 0010100012 = 10100012;
1718 = 0011110012 = 11110012;
6916 = 011010012 = 11010012.
2. Количество цифр во всех ответах одинаково, следовательно, нужно
выполнять сложение в двоичной системе счисления.
438
1
0
0
0
1
1
5616
1 0
1
0
1
1
0
сумма
0
0
1
1 1
1
1
Единицы в старших разрядах суммы позволяют быстро сравнить числа.
Ответ: 2.
20
B3 (5 мин)
Укажите через запятую в порядке возрастания все десятичные числа,
не превосходящие 25, запись которых в системе счисления с основанием
четыре оканчивается на 11.
РЕШЕНИЕ
Рассмотрим 2 варианта решения этой задачи.
Решение А: от десятичной к 4-ричной.
1. Вычислим, сколько десятичных единиц составляют 114 :
114 = 1*4 + 1 = 510. Это первое число, которое удовлетворяет условию
задачи. Разницу 25 – 5 = 20 могут восполнить старшие разряды 4-ричного
числа.
2. Вычислим, сколько десятичных единиц составляют 1114 :
1114 = 1*42 + 1*4 + 1 = 1*16 + 4 + 1 = 2110. Это второе число, которое
удовлетворяет условию задачи.
3. Следующее число, которое нужно проверить – 2114. Однако из
предыдущего вычисления уже понятно, что десятичное значение будет
больше 25.
Ответ: 5,21
Решение Б: от 4-ричной к десятичной.
1. Переведем число 2510 в 4-ричную систему счисления:
25 | 4
24 6 | 4
1 4 1
2
2510 = 1214.
2. Выпишем все 4-ричные числа, удовлетворяющие условию задачи:
114, 1114.
3. Переведем найденные числа в десятичную систему счисления.
114 = 1*4 + 1 = 5; 1114 = 1*42 + 1*4 + 1= 21.
Ответ: 5,21
21
4. КОДИРОВАНИЕ ИНФОРМАЦИИ
Оперативная память компьютера состоит из элементов, которые могут
находиться только в одном из двух состояний: включено – выключено,
да – нет, 1 – 0. Поэтому информацию, которую требуется сохранить в памяти, предварительно нужно закодировать двоичным кодом. Для каждого
вида информации (числа, символы, команды) применяются свои правила
кодирования.
В зависимости от применяемого способа кодирования внутреннее (в
оперативной памяти) представление информации может иметь разную
длину.
Может потребоваться кодировать информацию не двоичным, а какимлибо другим кодом, который используется в памяти вычислительного
устройства.
Нужно уметь определять длину закодированного сообщения или вычислять минимальную длину кода для одного элемента данных. Эти вычисления базируются на определенном соотношении.
Введем обозначения:
S – число возможных состояний одного разряда кода. Для памяти компьютера S=2;
D – минимальная длина кода, достаточное количество разрядов кода
для кодирования некоторого набора значений данных. Например,
для кодирования символов в памяти компьютера применяются
значения D, равные 8 или 16;
N – количество разных кодов, которые можно получить при заданных
S и D.
Между этими величинами выполняется соотношение: N = SD. Оно является основой для вычислений. Например, нужно закодировать набор из
100 разных значений с помощью устройств, которые могут находиться в
трех разных состояниях. Значит, известно, что N=100, S=3. Требуется
найти такое D, чтобы общая длина закодированного сообщения была минимальной.
Преобразуем соотношение таким образом, чтобы выразить неизвестную величину: D = logS N. Поскольку количество разрядов должно быть
целым, следует округлить вычисленное значение до ближайшего целого
сверху. Итак, D = log3 100 → 5.
22
A1 (1 мин)
Автоматическое устройство осуществило перекодировку информационного сообщения на русском языке, первоначально записанного в 16битном коде Unicode, в 8-битную кодировку КОИ-8. При этом информационное сообщение уменьшилось на 480 бит. Какова длина сообщения в
символах?
1) 30
2) 60
3) 120
4) 480
РЕШЕНИЕ
8-битный код информационного сообщения в 2 раза меньше 16битного кода того же сообщения. Значит, 480 бит составляют длину 8битного кода. Следовательно, количество символов в сообщении равно
480 / 8 = 60. Ответ: 2.
A2 (3 мин)
В велокроссе участвуют 119 спортсменов. Специальное устройство регистрирует прохождение каждым из участников промежуточного финиша,
записывая его номер с использованием минимально возможного количества бит, одинакового для каждого спортсмена. Каков информационный
объем сообщения, записанного устройством, после того как промежуточный финиш прошли 70 велосипедистов?
1) 70 бит
2) 70 байт
3) 490 бит
4) 119 байт
РЕШЕНИЕ
Применим соотношение: N = SD. В задаче N=119, S=2, поскольку код
составляется из бит, т.е. двоичных разрядов.
1. Для записи каждого из 119 разных номеров спортсменов с помощью
наиболее короткого кода требуется (log2 119) бит. Поскольку количество
бит должно быть целым, следует округлить вычисленное значение до ближайшего целого сверху, т.е. до 7.
2. Длина кода для 70 спортсменов составляет 7 * 70 = 490 бит.
Ответ: 3.
23
A11 (1 мин)
Для кодирования букв А, Б, В, Г решили использовать двухразрядные
последовательные двоичные числа (от 00 до 11, соответственно). Если таким способом закодировать последовательность символов БАВГ и записать результат шестнадцатеричным кодом, то получится
1) 4B
2) 411
3) BACD
4) 1023
РЕШЕНИЕ
Рассмотрим два варианта решения.
Решение А: выполнение кодирования и перевода.
1. Запишем таблицу кодов:
А 00
Б 01
В 10
Г 11
2. Сформируем двоичный код последовательности символов БАВГ:
01 00 10 11.
3. Переведем полученный код в 16-ричное представление, используя
соотношение 16 = 24. Разделим код на четверки разрядов и каждую четверку заменим соответствующей ей 16-ричной цифрой: 4 B.
Ответ: 1.
Решение Б: вычисление длины кода.
Длина двоичного кода равна 2 * 4 = 8. Следовательно, в 16-ричном
представлении получится 2 цифры. Отсюда ответ: 1.
B1 (1 мин)
Световое табло состоит из лампочек. Каждая лампочка может находиться в одном из трех состояний («включено», «выключено» или «мигает»). Какое наименьшее количество лампочек должно находиться на табло,
чтобы с его помощью можно было передать 18 различных сигналов?
РЕШЕНИЕ
Применим соотношение: N = SD. В задаче N=18, S=3.
24
Для записи каждого из 18 разных сигналов с помощью наиболее короткого троичного кода требуется (log3 18) разрядов (лампочек). Поскольку количество разрядов должно быть целым, следует округлить вычисленное значение до ближайшего целого сверху, т.е. до 3.
Ответ: 3
25
5. ИНФОРМАЦИОННЫЕ ТЕХНОЛОГИИ
В заданиях, относящихся к этой теме, требуется умение работать в
приложениях операционной системы с электронными таблицами, базами
данных и электронными изображениями, создавать Web-страницы, выполнять операции с файлами.
A13 (1 мин)
Для групповых операций с файлами используются маски имен файлов. Маска представляет собой последовательность букв, цифр и прочих
допустимых в именах файлов символов, в которых также могут встречаться следующие символы:
Символ «?» (вопросительный знак) означает ровно один произвольный
символ.
Символ «*» (звездочка) означает любую последовательность символов
произвольной длины, в том числе «*» может задавать и пустую последовательность.
Определите, какое из указанных имен файлов удовлетворяет маске:
?hel*lo.c?*.
1) hello.c
2) hello.cpp
3) hhelolo.cpp
4) hhelolo.c
РЕШЕНИЕ
1. Символ «?» в начале маски означает, что перед символами «hel»
должен быть один и только один символ. Значит, ответы 1 и 2 не верны.
2. Символ «?» в конце маски означает, что после символа «c» должен
быть один и только один символ. Значит, ответ 4 неверный.
3. Несмотря на то, что остался один вариант ответа, убедимся, что он
верный. Символ «*» означает любую последовательность, первая «*» –
«o», вторая – «p».
Ответ: 3.
A14 (2 мин)
Результаты тестирования представлены в таблице:
26
Фамилия
Пол
Аганян
Воронин
Григорчук
Роднина
Сергеенко
Черепанова
ж
м
м
ж
ж
ж
Математика
82
43
54
71
33
18
Русский
язык
56
62
74
63
25
92
Химия
46
45
68
56
74
83
Информатика
32
74
75
82
38
28
Биология
70
23
83
79
46
61
Сколько записей в ней удовлетворяют условию
«Пол=’ж’ ИЛИ Химия>Биология»?
1) 5
2) 2
3) 3
4) 4
РЕШЕНИЕ
Для ответа нужно выделить подмножества записей, удовлетворяющие
отдельным частям условия, а затем выполнить объединение этих подмножеств. Поскольку в таблице нет номеров записей, удобно обозначать каждую запись, например, первой буквой фамилии (в задании эти буквы разные).
Условию «Пол=’ж’» удовлетворяют записи А, Р, С, Ч.
Условию «Химия>Биология» удовлетворяют записи В, С, Ч.
Объединение полученных подмножеств: А, Р, С, Ч, В.
Ответ: 1.
A15 (2 мин)
Для кодирования цвета фона страницы Интернет используется атрибут
bgcolor="#ХХХХХХ", где в кавычках задаются шестнадцатеричные значения интенсивности цветовых компонент в 24-битной RGB-модели.
Какой цвет будет у страницы, заданной тэгом
<body bgcolor="#FFFFFF">?
1) белый
2) зеленый
3) красный
4) синий
27
РЕШЕНИЕ
1. В 24-битной цветовой модели RGB код цвета определяется вкладом
каждого из трех базовых цветов. Код базового цвета занимает 8 бит, т.е. 1
байт. Минимальное значение кода базового цвета – 00000000, максимальное 11111111. Первый байт – код красной (R) составляющей цвета точки,
второй байт – код зеленой составляющей (G), третий байт – код синей составляющей (B).
2. В графических приложениях принято обозначать код цвета с помощью 16-ричных чисел. Следовательно, каждый базовый цвет в коде отображается двумя 16-ричными цифрами. Минимальное значение кода базового цвета – 00, максимальное значение FF. Символ «#» указывает на то,
что это код.
3. В задании приводится код цвета, в который все базовые цвета дают
максимальный вклад, значит – это белый цвет.
Ответ: 1.
A16 (1 мин)
В электронной таблице значение формулы =СУММ(B1:B2) равно 5.
Чему равно значение ячейки B3, если значение формулы =СРЗНАЧ(B1:B3)
равно 3?
1) 8
2) 2
3) 3
4) 4
РЕШЕНИЕ
Если среднее значение трех чисел равно 3, то сумма этих чисел равна
3*3 = 9. Следовательно, в ячейке B3 находится число 9 – 5 = 4.
Ответ: 4.
A17 (3 мин)
На диаграмме показано количество призеров олимпиады по информатике (И), математике (М), физике (Ф) в трех городах России.
28
Какая из диаграмм правильно отражает соотношение общего числа
призеров по каждому предмету для всех городов вместе?
РЕШЕНИЕ
По столбчатой диаграмме можно определить общее количество призеров по каждому предмету.
(М) = 180 + 160 + 180 = 520;
(Ф) = 120 + 140 + 120 = 380;
(И) = 120 + 60 + 120 = 300.
Сравнение полученных трех чисел и образцов круговых диаграмм позволит быстро найти правильный ответ. (Ф) + (И) = 680, т.е. (М) меньше
половины всех призеров. Значит, ответы 2 и 3 не верны. (И) меньше (Ф),
значит, ответ 4 не верный.
Ответ: 1.
29
B7 (3 мин)
Скорость передачи данных через ADSL-соединение равна 128000
бит/c. Через данное соединение передают файл размером 625 Кбайт. Определите время передачи файла в секундах.
РЕШЕНИЕ
Все заданные величины нужно привести к одним единицам измерения,
либо скорость в Кбайт/с, либо размер файла в битах, либо скорость в
Байт/с и размер файла в байтах. Например,
625  1024 625  1024 25  1024 25  16 25  8




 5  8  40.
128000 8
16000
640
10
5
Ответ: 40
B9 (3 мин)
Петя записал IP-адрес школьного сервера на листке бумаги и положил
его в карман куртки. Петина мама случайно постирала куртку вместе с запиской. После стирки Петя обнаружил в кармане четыре обрывка с фрагментами IP-адреса. Эти фрагменты обозначены буквами А, Б, В и Г. Восстановите IP-адрес.
В ответе укажите последовательность букв, обозначающих фрагменты,
в порядке, соответствующем IP-адресу.
РЕШЕНИЕ
IP-адрес не может начинать с точки, значит A не первая часть. За А не
могут идти никакие части, потому что получатся слишком большие значения (> 255), следовательно, это последняя часть. Г не может следовать ни
за какой частью, потому что получатся слишком большие значения, следовательно, это начало. Б и В следуют друг за другом.
Ответ: ГБВА
30
B10 (5 мин)
В таблице приведены запросы к поисковому серверу. Расположите номера запросов в порядке возрастания количества страниц, которые найдет
поисковый сервер по каждому запросу.
Для обозначения логической операции “ИЛИ” в запросе используется
символ |, а для логической операции “И” – &.
1
2
3
4
принтеры & сканеры & продажа
принтеры & продажа
принтеры | продажа
принтеры | сканеры | продажа
РЕШЕНИЕ
Запрос, содержащий несколько операций «И», задает самые большие
ограничения на поиск. Следовательно, количество найденных страниц будет наименьшим. С другой стороны, запрос, содержащий несколько операций «ИЛИ», задает самые маленькие ограничения на поиск. Следовательно, количество найденных страниц будет наибольшим. Между этими запросами разместятся 2 и 3.
Ответ: 1234
31
6. АНАЛИЗ АЛГОРИТМОВ
В заданиях предложены фрагменты программ для конкретных исполнителей: компьютера или некоего робота. Для ответа на тестовый вопрос
требуется выполнить эти программы, так сказать, вручную. Рекомендуется
начертить таблицу, в которой будут фиксироваться постепенно изменяющиеся значения переменных, или сделать поясняющий рисунок.
A5 (2 мин)
Определите значение переменной c после выполнения следующего
фрагмента программы.
Бейсик
a=5
a=a+6
b=–a
c=a–2*b
1) c = –11
Паскаль
a:=5;
a:=a+6;
b:= –a;
c:=a–2*b;
2) c = 15
Алгоритмический
a:=5
a:=a+6
b:= –a
c:=a–2*b
3) c = 27
4) c = 33
РЕШЕНИЕ
a
5
11
b
c
-11
33
Ответ: 4.
A6 (4 мин)
Дан фрагмент программы, обрабатывающей двухмерный массив A
размера n x n.
32
Бейсик
k=1
FOR i = 1 TO n
c = A(i,i)
A(i,i) = A(k,i)
A(k,i) = c
NEXT i
Паскаль
k:=1;
for i:=1 to n do
begin
c:=A[i,i];
A[i,i]:=A[k,i];
A[k,i]:=c
end
Алгоритмический
k:=1
нц для i от 1 до n
c:=A[i,i]
A[i,i]:=A[k,i]
A[k,i]:=c
кц
Представим массив в виде квадратной таблицы, в которой для элемента массива A[i,j] величина i является номером строки, а величина j – номером столбца, в котором расположен элемент. Тогда данный алгоритм меняет местами
1) два столбца в таблице
2) две строки в таблице
3) элементы диагонали и k-ой строки таблицы
4) элементы диагонали и k-го столбца таблицы
РЕШЕНИЕ
Пусть n=3. Начертим заданную таблицу и в каждую клетку поместим
обозначение соответствующего элемента двухмерного массива:
Номера
строк
1
2
3
Номера столбцов
1
2
3
A[1, 1]
A[1, 2]
A[1, 3]
A[2, 1]
A[2, 2]
A[2, 3]
A[3, 1]
A[3, 2]
A[3, 3]
У элементов, стоящих на главной диагонали, номер строки совпадает с
номером столбца. Следовательно, A[i,i] – это элемент, стоящий на главной
диагонали таблицы на пересечении i-й строки и i-го столбца. В цикле for
i:=1 to n перебираются все элементы диагонали, значит, ответы 1) и 2) не
верны.
На каждом шаге выполнения цикла for i:=1 to n очередной элемент
диагонали A[i,i] меняется местами с элементом A[k,i], который находится
на пересечении k-й строки и i-го столбца. В цикле изменяется i, т.е. номер
столбца для A[k,i], а номер строки k не изменяется, следовательно, перебираются все элементы k-й строки.
Ответ: 3.
33
A18 (5 мин)
Система команд исполнителя РОБОТ, «живущего» в прямоугольном
лабиринте на клетчатой плоскости:
вверх
вниз
влево
вправо
При выполнении любой из этих команд РОБОТ перемещается на одну
клетку соответственно: вверх ↑, вниз ↑, влево ←, вправо →.
Четыре команды проверяют истинность условия отсутствия стены у
каждой стороны той клетки, где находится РОБОТ:
сверху свободно снизу свободно слева свободно справа свободно
Цикл
ПОКА < условие > команда
выполняется, пока условие истинно, иначе происходит переход на следующую строку.
Сколько клеток приведенного лабиринта соответствуют требованию,
что, выполнив предложенную ниже программу, РОБОТ остановится в той
же клетке, с которой он начал движение?
1) 1
2) 2
3) 3
4) 0
РЕШЕНИЕ
Проанализируем, каким условиям должна удовлетворять клетка, с которой начнется и в которой закончится движение.
1. Первые передвижения робота – вниз. Начальная клетка может быть
свободна снизу, и робот начнет перемещаться. С другой стороны, в этой
клетке снизу может оказаться стена, и первый цикл ПОКА не выполнит ни
34
одного перемещения. Но это не является причиной выбросить такие клетки
из рассмотрения. Например, в лабиринте, изображенном на рисунке ниже,
клетка удовлетворяет условию задачи:
2. После всех перемещений робот должен остановиться в начальной
клетке. Последний цикл ПОКА перемещает робота вправо, значит, робот
остановится, натолкнувшись на правую стену клетки. Следовательно, в
качестве начальных нужно рассматривать только те клетки, у которых
есть правая стена. Это A1, B2, C6, E5 и весь столбец F.
3. Единственная клетка, удовлетворяющая условию задачи – F4.
Ответ: 1.
B2 (1 мин)
Запишите значение переменной b после выполнения фрагмента
алгоритма:
Примечание: знаком := обозначена операция присваивания,
знаком * обозначена операция умножения.
35
РЕШЕНИЕ
a
b
a=25
6
1
2
4
8
16
32
64
128
256
1
3
7
15
31
63
127
255
511
нет
нет
нет
нет
нет
нет
нет
нет
да
Ответ: 511
C1 (30 мин)
Требовалось написать программу, которая вводит с клавиатуры координаты точки
на плоскости (x,y – действительные числа) и
определяет принадлежность точки заштрихованной области, включая ее границы.
Программист торопился и написал программу неправильно.
36
ПРОГРАММА НА
ПАСКАЛЕ
var x,y: real;
begin
readln(x,y);
if y<=1 then
if x>=0 then
if y>=sin(x) then
write('принадлежит')
else
write('не принадлежит')
end.
ПРОГРАММА НА
ПРОГРАММА НА СИ
БЕЙСИКЕ
INPUT x, y
void main(void)
IF y<=1 THEN
{ float x,y;
IF x>=0 THEN
scanf("%f%f",&x,&y);
IF y>=SIN(x) THEN
if (y<=1)
PRINT "принадлежит" if (x>=0)
ELSE
if (y>=sin(x))
PRINT"не принадлежит" printf("принадлежит");
ENDIF
else
ENDIF
printf("не принадлеENDIF
жит");
END
}
Последовательно выполните следующее:
1) Приведите пример таких чисел x, y, при которых программа неверно
решает поставленную задачу.
2) Укажите, как нужно доработать программу, чтобы не было случаев
ее неправильной работы. (Это можно сделать несколькими способами, поэтому можно указать любой способ доработки исходной программы.)
РЕШЕНИЕ
1. Рекомендуется переписать на черновик программу так, чтобы хорошо была видна вложенность операторов:
var x,y: real;
begin
readln(x,y);
if y<=1 then
if x>=0 then
if y>=sin(x) then
write('принадлежит')
else
write('не принадлежит')
end.
Из этой записи сразу видно, что при y>1 программа вообще ничего не
выводит, вне зависимости от значения x. Один из правильных ответов
на первый вопрос: при y>1 и любом x.
37
2. Лучший способ доработки программы – написать ее заново самостоятельно.
Отобразим на чертеже влияние последовательности условий, приведенных в решении:
Штриховкой выделены части координатной плоскости, не принадлежащие нужной области. Вертикальная штриховка соответствует условию
(y <= 1), горизонтальная – (x >= 0), наклонная – (y >= sin x). Видно, что в
программе отсутствует еще одно условие – (x <= π/2).
Один из вариантов правильной программы:
var x,y: real;
begin
readln(x,y);
if (y<=1) and (x>=0) and (y>=sin(x)) and (x<=3.14/2) then
write('принадлежит')
else write('не принадлежит')
end.
38
7. РАЗРАБОТКА АЛГОРИТМОВ
Процесс разработки алгоритма и составления программы для компьютера может быть достаточно сложным. Рекомендуется выполнять его планомерно, придерживаясь определенной последовательности действий.
1. Входные данные: отдельные переменные и массивы, типы данных,
наличие особенностей в значениях. Описание и комментирование, ввод.
2. Результаты: переменные и массивы, типы, связь между количеством входных значений и количеством результатов. Описание и комментирование, вывод.
3. Тесты: наборы входных значений, для которых известны результаты. Учет возможных особенностей во входных значениях.
4. Разработка алгоритма: создание общей схемы алгоритма как системы взаимодействующих или последовательных блоков действий, детальная проработка каждого из этих блоков. Разрешается использование
любых форм записи алгоритма. Рекомендуется там, где можно, сразу использовать алгоритмическую нотацию, т.е. операторы языка программирования.
5. Запись программы: на основе разработанного алгоритма программа
собирается из отдельных готовых фрагментов.
В задачах повышенной сложности требуется написать как можно более
эффективную программу.
Эффективность программы оценивается по уровню использования ею
ресурсов компьютера: процессорного времени и оперативной памяти.
Например, из двух программ, написанных для решения одной и той же задачи, более эффективной будет та, которая формирует результат путем
выполнения меньшего количества элементарных действий. Говорят, что
эта программа имеет большее быстродействие. Для оценки эффективности
программы определяется функция зависимости количества элементарных
действий от размера входных данных. Эту функцию называют трудоемкостью. Более эффективной является программа, обладающая меньшей
трудоемкостью.
Если говорить об использовании оперативной памяти, то более эффективной считается программа, хранящая в памяти только безусловно необходимую информацию.
Итак, наиболее эффективная программа потребляет меньше ресурсов.
Но обычно сэкономить одновременно на всех ресурсах не удается, поэто-
39
му нужен разумный компромисс между быстродействием и потреблением
памяти.
B5 (6 мин)
У исполнителя Калькулятор две команды, которым присвоены номера:
1. прибавь 3
2. умножь на 4
Выполняя первую из них, Калькулятор прибавляет к числу на экране 3,
а выполняя вторую, умножает его на 4. Запишите порядок команд в программе получения из числа 3 числа 57, содержащей не более 6 команд,
указывая лишь номера команд.
(Например, программа 21211 это программа
умножь на 4
прибавь 3
умножь на 4
прибавь 3
прибавь 3
которая преобразует число 2 в 50.)
РЕШЕНИЕ
Задачу удобнее решать от конца к началу. Получить в конце 57 можно
только после выполнения команды прибавь 3. Значит, предыдущее значение будет 57–3 = 54. Это значение не делится на 4, значит, тоже получится
после команды прибавь 3. 54–3 =51. И это значение получится в результате выполнения прибавь 3. 51–3 = 48. 48 делится на 4, следовательно, получится после выполнения умножь на 4. 48 / 4 = 12. Число 12 может получиться после выполнения умножь на 4. 12 / 4 = 3. Итак, нужно выполнить
такую последовательность команд: *4 *4 +3 +3 +3. Их всего 5.
Ответ: 22111
C2 (30 мин)
Опишите на русском языке или одном из языков программирования
алгоритм получения из заданного целочисленного массива размером 30
элементов другого массива, который будет содержать модули значений
элементов первого массива (не используя специальной функции, вычисляющей модуль числа).
40
РЕШЕНИЕ
Пусть X – некоторая величина со знаком, а Y = |X| – модуль (абсолютное значение) X. Правило вычисления модуля:
 X , если X  0,
Y 
 X , если X  0.
Следовательно, каждый элемент исходного массива нужно сравнить с
0. Если значение элемента больше или равно 0, то оно присваивается соответствующему элементу выходного массива. Если значение элемента исходного массива меньше 0, то оно умножается на (–1) и присваивается соответствующему элементу выходного массива.
Программа на Паскале:
const N = 30;
var a, b : array [1..N] of integer;
i : integer;
begin
for i := 1 to N do
read (a[i]);
for i := 1 to N do
if a[i] < 0
then b[i] := –a[i]
else b[i] := a[i];
for i := 1 to N do
write (b[i]);
end.
C4 (60 мин)
На вход программе подаются сведения о номерах школ учащихся,
участвовавших в олимпиаде. В первой строке сообщается количество учащихся N, каждая из следующих N строк имеет формат:
<Фамилия> <Инициалы> <номер школы>,
где <Фамилия> – строка, состоящая не более чем из 20 символов,
<Инициалы> – строка, состоящая из 4-х символов (буква, точка,
буква, точка),
41
<номер школы> – не более чем двузначный номер.
<Фамилия> и <Инициалы>, а также <Инициалы> и <номер школы>
разделены одним пробелом. Пример входной строки:
Иванов П.С. 57
Требуется написать как можно более эффективную программу (укажите используемую версию языка программирования, например, Borland
Pascal 7.0), которая будет выводить на экран информацию, из какой школы
было меньше всего участников (таких школ может быть несколько). При
этом необходимо вывести информацию только по школам, пославшим хотя бы одного участника.
Следует учитывать, что N>=1000.
РЕШЕНИЕ
Задача, предложенная в этом задании, сложная, поэтому будет решать
ее, придерживаясь рекомендованного плана действий.
1. Входные данные. Значения входных данных находятся в строках
символов. Значит, для ввода понадобится символьная (char) или строковая (string) переменная.
Все строки, кроме первой, очень простой, имеют одинаковый формат:
сведения об одном ученике. Возникает вопрос, все ли эти сведения нужны
для решения задачи? Программа должна выводить совокупную информацию по школам, без перечисления фамилий и инициалов участников, т.е.
для вывода результатов фамилии и инициалы не нужны. Но, может быть,
они понадобятся в ходе решения? Пока четко ответить на этот вопрос
нельзя – нет алгоритма. Но определенно ясно, что номера школ нужны.
Поэтому можно предварительно рассчитывать на ввод только номеров
школ и попытаться при разработке алгоритма оперировать только этой
информацией.
Номер школы нужно извлечь из строки символов. Для этого ее следует
проанализировать по отдельным символам. Группа символов до первого
пробела – фамилия, мы решили, что ее запоминать не нужно. Между первым и вторым пробелами – инициалы, которые тоже не будем запоминать.
За вторым пробелом – нужный нам номер школы, состоящий из одного
или двух символов.
Таким образом, мы приходим к выводу: для заполнения входных данных значениями, нужно написать алгоритм, который извлекает эти значения из строк символов. Поскольку все символы, кроме одного или двух
последних, нужно просто читать из строки и никуда не записывать, удоб-
42
нее использовать для этого символьную переменную. А вот номер школы
лучше сразу читать из строки ввода как число, обратив внимание на указание в условии задачи, что номера школ не более чем двузначные числа, т.е.
находятся в диапазоне от 1 до 99. Описание переменных:
var N : integer;
sym : char;
nschool : 1..99; {или nschool : integer;}
i : integer;
Можно оформить ввод:
readln(N);
for i : =1 to N do begin
sym := ‘!’; {этот символ не может быть в начале фамилии}
while sym <> ‘ ‘ do {чтение фамилии}
read(sym);
sym := ‘!’;
while sym <> ‘ ‘ do {чтение инициалов}
read(sym);
readln(nschool);
{следующий ввод – с новой строки}
использование переменной nschool;
end;
Содержимое блока «использование переменной nschool» будет разработано позже.
2. Результаты. Номера школ, из которых было меньше всего участников, нужно вывести на экран. Таким образом, значения результатов можно
не сохранять в памяти, а получать по ходу решения и сразу выводить. Следовательно, при разработке алгоритма возникнет необходимость использования дополнительных переменных для хранения промежуточных результатов.
3. Тесты. Хотя бы один тест нужен для более глубокого понимания задачи. Поскольку фамилия и инициалы не играют важной роли, обратим
внимание на номера школ. Тест представим в виде таблицы:
43
Фамилия
Инициалы
Номер школы
А
К
5
Б
Л
93
В
М
5
Г
Н
93
Д
О
2
E
П
83
Ж
Р
5
З
С
2
И
Т
74
Ответ: школы 83, 74.
Номера школ при вводе следуют не по порядку, значит, только прочитав сведения обо всех учениках, мы сможем сделать вывод о школах с малым количеством участников олимпиады. Возникает необходимость в
накоплении информации по всем школам, т.е. сохранении ее в массиве.
Эту проблему предстоит решить при составлении алгоритма.
4. Разработка алгоритма. Общая схема алгоритма может иметь следующий вид:
начальные значения;
сбор сведений обо всех школах;
поиск минимального количества участников из одной школы;
вывод номеров школ с минимальным количеством участников;
Проведем детализацию отдельных блоков алгоритма.
сбор сведений обо всех школах
Заполнение массива с количеством учеников в каждой школе. Смысл
этого массива – набор счетчиков. Каждый элемент относится к определенной школе. Вспомнив еще раз, что номера школ берутся из ограниченного
интервала значений, делаем самый важный для решения задачи вывод: бу-
44
дем использовать массив счетчиков, в котором номера элементов являются
номерами школ. Описание этого массива:
var count : array[1..99] of integer;
Счетчики заполняются в процессе чтения данных из строк ввода. Для
этих действий в цикле ввода мы оставили пояснение «использование переменной nschool». Сейчас стало понятно, как связать эту переменную с
массивом:
count[nschool] := count[nschool] + 1;
поиск минимального количества участников из одной школы
Это поиск минимума в массиве count среди школ, имеющих участников олимпиады.
min := N; {нельзя взять count[1], т.к. там может быть 0}
for i := 1 to 99 do
if count[i] > 0
then begin if count[i] < min
then min := count[i];
end;
вывод номеров школ с минимальным количеством участников
for i := 1 to 99 do
if count[i] = min
then writeln (i);
начальные значения
Обнуление массива счетчиков:
for i := 1 to 99 do
count[i] = 0;
На этом разработка алгоритма закончена.
45
5. Запись программы.
var N : integer;
sym : char;
nschool : 1..99;
count : array[1..99] of integer;
i, min : integer;
begin
for i := 1 to 99 do
count[i] = 0;
readln(N);
for i : =1 to N do begin
sym := ‘!’;
while sym <> ‘ ‘ do
read(sym);
sym := ‘!’;
while sym <> ‘ ‘ do
read(sym);
readln(nschool);
count[nschool] := count[nschool] + 1;
end;
min := N;
for i := 1 to 99 do
if count[i] > 0
then begin if count[i] < min
then min := count[i];
end;
for i := 1 to 99 do
if count[i] = min
then writeln (i);
end.
Рассмотрим решение ряда задач повышенной сложности.
46
Т е м п е р а т у р а . На вход программе подаются 365 строк, которые
содержат информацию о среднесуточной температуре всех дней 2007 года.
Формат каждой из строк следующий: сначала записана дата в виде dd.mm
(на запись номера дня и номера месяца в числовом формате отводится
строго два символа, день от месяца отделен точкой), затем через пробел
(для Бейсика – через запятую) записано значение температуры – число со
знаком плюс или минус, с точностью до 1 цифры после десятичной точки.
Данная информация отсортирована по значению температуры, то есть хронологический порядок нарушен. Требуется написать как можно более эффективную программу, которая будет определять и выводить на экран
максимальное отклонение среди всех дней года среднесуточной температуры от соответствующей этим дням среднемесячной. Пример строки
входных данных:
19.01 -25.6
1. Входные данные. Значения входных данных находятся в строках
символов. Значит, для ввода понадобится символьная (char) или строковая (string) переменная.
Строки имеют одинаковый формат: сведения об одном дне года. Возникает вопрос, все ли эти сведения нужны для решения задачи?
Для определения максимального отклонения нужно вычислить среднемесячную температуру, а затем сравнить ее со среднесуточными температурами. Следовательно, набор среднесуточных температур для каждого
месяца должен находиться в памяти.
Номер месяца из вводимой даты требуется только для того, чтобы отнести температуру к определенному месяцу. Это приводит к идее расположения набора температур в памяти по месяцам без отдельного сохранения номеров месяцев.
День месяца в вычислениях вообще не используется, возможно, его не
нужно сохранять.
Используя приведенные рассуждения, можно записать алгоритм извлечения нужной информации из строки ввода: сначала читаются 3 символа, а
затем 2 числа. Описание переменных:
const N = 365;
var sym : char;
month : 1..12; {или month : integer;}
temperature : real;
47
i : integer;
Можно оформить ввод:
for i : =1 to N do begin
for j := 1 to 3 do {чтение номера дня и точки}
read(sym);
read(month); {чтение номера месяца}
readln(temperature); {следующий ввод – с новой строки}
использование переменных month и temperature;
end;
Содержимое блока «использование переменных month и temperature»
будет разработано позже.
2. Результаты. Для вычисления максимального отклонения потребуется переменная, с которой как с образцом будут сравниваться все отклонения. В итоге именно значение этой переменной станет ответом. Описание
переменной:
var max_otkl : real;
3. Тесты. Полный перечень всех дней, естественно, приводить в тесте
не нужно. Но хотя бы один упрощенный тест нужен для более глубоко понимания задачи. Представим входные значения в виде таблицы:
Номер дня и
точка
Номер месяца
Температура
19.
01
-25.6
05.
05
+12.5
23.
01
-15.8
01.
05
+10.6
31.
12
-5.3
23.
10
+7.9
29.
01
-17.2
01.
12
-21.9
08.
03
+3.9
Результаты вычислений (абсолютное значение отклонения):
48
Номер
месяца
01
03
05
10
12
Среднемесячная температура
(–25.6 –15.8 –17.2) / 3 = –19.5
+3.9 / 1 = +3.9
(+12.5 +10.6) / 2 = +11.6
+7.9 / 1 = +7.9
(–5.3 –21.9) / 2 = –13.6
Максимальное отклонение в
месяце
6.1
0.0
1.0
0.0
8.3
Ответ: максимальное отклонение среди всех дней года среднесуточной
температуры от соответствующей этим дням среднемесячной равно 8.3.
Номера месяцев при вводе следуют не по порядку, значит, только прочитав все сведения, мы сможем вычислить среднемесячные температуры, а
затем сравнить отклонения среднесуточных от среднемесячных. Возникает
необходимость в накоплении информации по всем месяцам, т.е. сохранении ее в массиве. Эту проблему предстоит решить при составлении алгоритма.
4. Разработка алгоритма. Общая схема алгоритма может иметь следующий вид:
начальные значения;
размещение необходимой информации в памяти;
для каждого месяца:
вычисление среднемесячной температуры;
определение максимального отклонения в сравнении с предыдущими месяцами;
Проведем детализацию отдельных блоков алгоритма.
размещение необходимой информации в памяти
Мы выяснили, что в памяти необходимо сохранять среднесуточные
температуры. Поскольку далее нужно будет вычислять среднемесячные
значения, вводимые данные следует сгруппировать по месяцам. Для этого
удобно применить двухмерный массив. Допустим, каждый столбец этого
массива соответствует определенному месяцу (номер столбца = номеру
месяца).
Из-за того, что данные во входных строках следуют не в хронологическом порядке, массив будет заполняться не постепенно, столбец за столбцом, а вразброс. Например, сначала запишется температура на 05.05, а
49
потом на 23.01, после этого на 01.05 и т.д. Значит, в каждом столбце в процессе ввода количество заполненных элементов будет разным, и нужно
знать, куда записать следующую температуру. Иными словами, нужны
счетчики для учета заполнения столбцов. Для исполнения этой роли можно использовать еще один дополнительный целочисленный массив из 12
элементов. Кстати, когда все данные будут прочитаны, в этом массиве
окажутся значения, равные количеству дней в месяце, они пригодятся для
вычисления среднемесячной температуры.
Если использовать предложенные структуры данных, то в двухмерный
массив можно добавить еще одну строку, в которой будут формироваться
среднемесячные значения температур непосредственно во время ввода.
Ниже приведен вид массивов для рассмотренного теста.
Номер месяца
Счетчик дней
1
3
2
0
3
1
4
0
5
2
…
10
1
11
0
12
2
Номер месяца
1
2
3
4
5
…
10
11
12
Среднесуточные
температуры
Среднемесячная
-25.6
-15.8
-17.2
+3.9
+12.5
+10.6
+7.9
-5.3
-21.9
Номер
строки
1
2
3
4
–19.5
+3.9
+11.6
+7.9
–13.6
31
32
Описание массивов:
var days : array[1..12] of integer;
tablica : array[1..32, 1..12] of real;
Разработанная структура данных позволяет изменить ранее намеченную последовательность действий в алгоритме: вычисление среднемесячной температуры переносится в блок размещения необходимой информации в памяти. Обновленная схема алгоритма:
начальные значения;
ввод и размещение необходимой информации в памяти;
для каждого месяца:
50
определение максимального отклонения в сравнении с предыдущими месяцами;
Получается, что «размещение необходимой информации в памяти» и
«использование переменных month и temperature» – это один и тот же
блок действий.
использование переменных month и temperature
days [month]:= days [month]+1; {место для температуры}
tablica[days [month], month]:= temperature;
tablica[32, month]:= tablica[32, month]+ temperature;
для каждого месяца
for i:=1 to 12 do begin
tablica[32, i]:= tablica[32, i] / days [i];
определение максимального отклонения в сравнении с предыдущими
месяцами
for j:=1 to days [i] do begin {по дням месяца}
if abs(tablica[j, i] – tablica[32, i]) > max_otkl
then max_otkl := abs(tablica[j, i] – tablica[32, i]);
начальные значения
После того, как детализированы отдельные блоки алгоритма, понятно,
что в начале программы нужно обнулить счетчики дней и накопители
сумм и задать значение переменной max_otkl.
for i:=1 to 12 do begin
days [i]:= 0;
tablica[32, i]:= 0;
end;
max_otkl:=0;
51
5. Запись программы.
const N = 365;
var sym : char;
month : 1..12;
temperature : real;
max_otkl : real;
days : array[1..12] of integer;
tablica : array[1..32, 1..12] of real;
I, j : integer;
begin
for i:=1 to 12 do begin
days [i]:= 0;
tablica[32, i]:= 0;
end;
max_otkl:=0;
for i : =1 to N do begin
for j := 1 to 3 do
read(sym);
read(month);
readln(temperature);
days [month]:= days [month]+1;
tablica[days [month], month]:= temperature;
tablica[32, month]:= tablica[32, month]+ temperature;
end;
for i:=1 to 12 do begin
tablica[32, i]:= tablica[32, i] / days [i];
for j:=1 to days [i] do begin
if abs(tablica[j, i] – tablica[32, i]) > max_otkl
then max_otkl := abs(tablica[j, i] – tablica[32, i]);
end;
writeln(max_otkl);
end.
52
П р о п и с н ы е б у к в ы . На вход программе подаются строчные и
прописные английские буквы. Ввод этих символов заканчивается точкой
(другие символы, отличные от «.», «a» .. «z», «A» .. «Z» во входных данных
отсутствуют, в программе на языке Бейсик символы можно вводить по одному в строке, пока не будет введена точка). Требуется написать как можно более эффективную программу, составляющую слово из тех букв английского алфавита, которые не встречаются во входных данных ни как
строчные, ни как прописные, причем буквы должны идти в алфавитном
порядке. Каждая буква должна быть распечатана один раз. Буквы построенного слова должны быть прописными. Если во входных данных встречаются все буквы английского алфавита, то следует вывести строчными
буквами слово «no».
Например, пусть на вход подаются следующие символы:
absCDKLMNOPvwXYabcprst.
В данном случае программа должна вывести
EFGHIJQUZ
1. Входные данные. В программе предполагается анализ каждого символа
входной строки. Если удастся разработать алгоритм, в котором этот анализ
производится без сравнения символов друг с другом, то не будет необходимости хранить их все в памяти. Тогда входным данным можно будет
считать символьную переменную. Описание переменной:
var sym : char;
Ввод символов из строки:
sym := ‘’;
while sym <> ‘.’ do begin
read(sym);
анализ символа;
end;
Содержимое блока «анализ символа» будет разработано позже.
2. Результаты. В соответствии с условием задачи найденные символы
не нужно отдельно сохранять в памяти.
3. Тесты. Тестом может служить пример, приведенный в условии.
4. Разработка алгоритма. Общая схема алгоритма может иметь следующий вид:
53
начальные значения;
размещение необходимой информации в памяти;
определение отсутствующих символов;
размещение необходимой информации в памяти
Чтобы не сравнивать символы друг с другом создадим дополнительный массив, в котором будем отмечать наличие символов из текста.
Значения кодов прописных букв английского алфавита следуют друг за
другом без пропусков, всего их 26. Строчные буквы можно преобразовать
в прописные с помощью функции upcase (символ). Применение этой
функции к прописной букве не меняет ее кода. Опишем дополнительный
массив, в котором каждый элемент связан с определенным символом алфавита – номер элемента равен коду символа, а значение элемента выступает в роли отметки о присутствии этого символа в тексте. Например, если
символа нет, то в соответствующем элементе массива – пробел, если символ есть, то – сам символ. Код символа вычисляется с помощью функции
ord (символ), символ определяется по коду с помощью функции chr (код).
Для теста массив будет иметь вид:
Номер
элемента
ord(‘A‘) ord(‘B‘) ord(‘C‘) … ord(‘J‘) … ord(‘Y‘) ord(‘Z‘)
A
B
C
Y
Описание массива:
var bukva : array[ ord(‘A’) .. ord(‘Z’) ] of char;
Теперь видно, что блок действий «размещение необходимой информации» включает в себя ввод и «анализ символа».
анализ символа
bukva [ord(upcase(sym))] := upcase(sym);
определение отсутствующих символов
yes :=0;
{подсчет присутствующих букв}
for i := ord(‘A’) to ord(‘Z’) do
if bukva[i] = ‘ ‘
54
then write (chr(i))
else yes := yes +1;
if yes = 26 then write(‘no’);
начальные значения
В массив bukva следует занести пробелы.
for i := ord(‘A’) to ord(‘Z’) do
bukva[i] := ‘ ‘;
5. Запись программы.
var sym : char;
bukva : array[ ord(‘A’) .. ord(‘Z’) ] of char;
i : integer;
begin
for i := ord(‘A’) to ord(‘Z’) do
bukva[i] := ‘ ‘;
sym := ‘’;
while sym <> ‘.’ do begin
read(sym);
bukva [ord(upcase(sym))] := upcase(sym);
end;
yes :=0;
for i := ord(‘A’) to ord(‘Z’) do
if bukva[i] = ‘ ‘
then write (chr[i])
else yes := yes +1;
if yes = 26 then write(‘no’);
end.
55
Ц и ф р ы . На вход программе подается последовательность символов,
среди которых встречаются и цифры. Ввод символов заканчивается точкой
(в программе на языке Бейсик символы можно вводить по одному в строке,
пока не будет введена точка). Требуется написать как можно более эффективную программу, которая составит из тех цифр, которые встречаются во
входных данных, максимальное число. При составлении итогового числа
каждая цифра может быть использована только один раз. Если во входных
данных цифры не встречаются, то следует вывести «-1».
Например, пусть на вход подаются следующие символы:
14ф73п49.
В данном случае программа должна вывести
97431
Идея решения полностью совпадает с задачей «прописные буквы».
1. Входные данные.
var sym : char;
2. Результаты. В соответствии с условием задачи найденные символы не
нужно отдельно сохранять в памяти.
3. Тесты. Тестом может служить пример, приведенный в условии.
4. Разработка алгоритма. Общая схема алгоритма может иметь следующий вид:
начальные значения;
размещение необходимой информации в памяти;
определение присутствующих цифр;
размещение необходимой информации в памяти
Во входной строке могут быть цифры и буквы (как английского, так и
русского алфавита). Следовательно, в дополнительном массиве должно
быть больше элементов, чем в задаче «Прописные буквы».
Описание массива:
var bukva : array[ ord(‘0’) .. ord(‘я’) ] of char;
Заполнение массива:
56
sym := ‘’;
while sym <> ‘.’ do begin
read(sym);
bukva [ord(sym)] := sym;
end;
определение присутствующих цифр
no := 0;
{подсчет отсутствующих цифр}
for i := ord(‘9’) downto ord(‘0’) do
if bukva[i] <> ‘ ‘
then write (chr[i])
else no := no +1;
if no = 10 then write(‘–1’);
начальные значения
В массив bukva следует занести пробелы.
for i := ord(‘0’) to ord(‘я’) do
bukva[i] := ‘ ‘;
57
5. Запись программы.
var sym : char;
bukva : array[ ord(‘0’) .. ord(‘я’) ] of char;
i, no : integer;
begin
for i := ord(‘0’) to ord(‘я’) do
bukva[i] := ‘ ‘;
sym := ‘’;
while sym <> ‘.’ do begin
read(sym);
bukva [ord(sym)] := sym;
end;
no := 0;
for i := ord(‘9’) downto ord(‘0’) do
if bukva[i] <> ‘ ‘
then write (chr(i))
else no := no +1;
if no = 10 then write(‘–1’);
end.
58
Ш и ф р о в а н и е . На вход программе подается текст заклинания, состоящего не более чем из 200 символов, заканчивающийся точкой (символ
«точка» во входных данных единственный). Оно было зашифровано Гарри
Поттером следующим образом. Сначала Гарри определил количество букв
в самом длинном слове, обозначив полученное число K (словом называется непрерывная последовательность английских букв, слова друг от друга
отделяются любыми другими символами, длина слова не превышает 20
символов). Затем он заменил каждую английскую букву в заклинании на
букву, стоящую в алфавите на K букв ранее (алфавит считается циклическим, то есть перед буквой A стоит буква Z), оставив другие символы
неизменными. Строчные буквы при этом остались строчными, а прописные – прописными. Требуется написать как можно более эффективную
программу, которая будет выводить на экран текст расшифрованного заклинания. Например, если зашифрованный текст был таким:
Zb Ra Ca,Dab Ra.
то результат расшифровки должен быть следующим:
Ce Ud Fd,Gde Ud.
1. Входные данные. Все символы из строки ввода понадобятся в алгоритме дважды: для вычисления максимальной длины слова и для расшифровки текста. Следовательно, их нужно сохранять в памяти, например, в символьной строке. Можно совместить ввод с вычислением максимальной
длины слова, тогда строку нужно считывать по символам, проверяя, буква
это или нет. В условии задачи предполагается, что буквы относятся к английскому алфавиту, значит, нужно сравнивать каждый вводимый символ
с 26-ю строчными и 26-ю прописными буквами. Наиболее удобный способ, позволяющий не использовать длинные цепочки if – then – else, заключается в представлении всех букв в виде множества: [‘A‘..‘Z‘, ‘a‘..‘z‘].
Описание переменных:
var sym : char;
zaklin_shifr : string;
K : integer;
Можно оформить ввод и вычисление максимальной длины слова:
K := 0; zaklin_shifr:=’’;
read(sym);
zaklin_shifr:= zaklin_shifr+sym;
while sym <> ‘.’ do begin
59
dlina := 0;
while (sym <> ‘.’) and (sym in [‘A‘..‘Z‘, ‘a‘..‘z‘]) do begin
dlina := dlina + 1; {подсчет длины очередного слова}
read(sym);
zaklin_shifr:= zaklin_shifr+sym;
end;
if K < dlina
then K := dlina;
while (sym <> ‘.’) and not((sym in [‘A‘..‘Z‘, ‘a‘..‘z‘])) do begin
read(sym);
zaklin_shifr:= zaklin_shifr+sym;
end;
end;
Замечание: в конце прочитанной строки стоит точка, т.е. преобразования нужно будет проводить до символа с номером length(zaklin_shifr)–1.
2. Результаты. Расшифрованная строка выводится на экран, хранить
ее в памяти не нужно.
3. Тесты. Тестом может служить пример, приведенный в условии.
4. Разработка алгоритма. Рассмотрим детально, как происходит замена одних букв на другие при расшифровке заклинания. Поскольку в процессе шифрования символы сдвигались циклически по алфавиту влево, для
расшифровки нужно выполнять сдвиг вправо. Пусть K = 3. Проиллюстрируем на фрагменте таблицы с прописными буквами английского алфавита,
как должны производиться замены.
Алфавит для зашифрованного
A B C D E F G …X Y Z
сообщения
Алфавит для расшифровки
D E F G H I J …A B C
Если в зашифрованном сообщении встретится буква ‘A‘, то на ее место
в расшифрованном сообщении должна встать буква ‘D‘, и т.д. Поскольку
K = 3, последние 3 буквы заменятся первыми тремя. Возникает идея: создать вспомогательный массив, в котором устанавливается соответствие
между буквами. Номера элементов этого массива – коды букв алфавита
для зашифрованного сообщения. Такая нумерация позволит по букве сразу
обратиться к значению элемента. Тогда значение элемента удобно сделать
равным букве, на которую нужно произвести замену. Или, чтобы облегчить вычисления, значение элемента можно сделать равным коду буквы
60
для замены. Снова обратимся к таблице, детализируя преобразования кодов:
Коды букв для
зашифрованного ord(‘A‘) …
ord(‘X‘)
сообщения
Коды букв для
ord(‘X‘)+K–
ord(‘A‘)+K …
расшифровки
26
ord(‘Y‘)
ord(‘Y‘)+K–
26
ord(‘Z‘)
ord(‘Z‘)+K–
26
K кодов
В заклинании кроме букв присутствуют другие символы, которые не
шифруются. Значит, во-первых, массив должен содержать все коды, вовторых, пересчитываются только буквенные коды. При 8-битном кодировании символов понадобится 28 = 256 элементов с номерами от 0 до 255.
Описание этого массива:
var code : array[0..255] of integer;
Общая схема алгоритма:
ввод и вычисление максимальной длины слова;
заполнение массива code;
расшифровка заклинания;
заполнение массива code
for i:=0 to 255 do code[i]:=i;
for i:=ord(‘A’) to ord(‘Z’)–K do
code[i]:=code[i]+K;
for i:=ord(‘Z’)–K+1 to ord(‘Z’) do
code[i]:=code[i]+K–26;
for i:=ord(‘a’) to ord(‘z’)–K do
code[i]:=code[i]+K;
for i:=ord(‘z’)–K+1 to ord(‘z’) do
code[i]:=code[i]+K–26;
расшифровка заклинания
for i:=1 to length(zaklin_shifr)–1 do
61
write(chr(code[ord(zaklin_shifr[i])]));
5. Запись программы.
var sym : char;
zaklin_shifr : string;
K : integer;
code : array[0..255] of integer;
i, dlina : integer;
begin
K := 0; zaklin_shifr:=’’;
read(sym);
zaklin_shifr:= zaklin_shifr+sym;
while sym <> ‘.’ do begin
dlina := 0;
while (sym <> ‘.’) and (sym in [‘A‘..‘Z‘, ‘a‘..‘z‘]) do begin
dlina := dlina + 1;
read(sym);
zaklin_shifr:= zaklin_shifr+sym;
end;
if K < dlina
then K := dlina;
while (sym <> ‘.’) and not((sym in [‘A‘..‘Z‘, ‘a‘..‘z‘])) do begin
read(sym);
zaklin_shifr:= zaklin_shifr+sym;
end;
end;
for i:=0 to 255 do code[i]:=i;
for i:=ord(‘A’) to ord(‘Z’)–K do
code[i]:=code[i]+K;
for i:=ord(‘Z’)–K+1 to ord(‘Z’) do
code[i]:=code[i]+K–26;
for i:=ord(‘a’) to ord(‘z’)–K do
code[i]:=code[i]+K;
for i:=ord(‘z’)–K+1 to ord(‘z’) do
code[i]:=code[i]+K–26;
for i:=1 to length(zaklin_shifr)–1 do
62
write(chr(code[ord(zaklin_shifr[i])]));
end.
63
8. ИГРЫ ДВУХ ПРОТИВНИКОВ
В этих играх игроки выполняют ходы поочередно, при этом обоим игрокам доступна вся информация о текущем состоянии игры. В таких играх
выигрыш одного игрока означает проигрыш другого. В теории игр доказано существование оптимальной (наилучшей) стратегии для каждого из игроков. Игрок, придерживающийся этой стратегии, гарантированно получит
выигрыш не меньше, чем заранее рассчитанный, как бы хорошо ни играл
его противник. Если же игрок будет отклоняться от этой стратегии, то он
может получить и меньший выигрыш, все зависит от ходов противника.
Для рассматриваемых игр оптимальной является минимаксная стратегия,
при которой на очередном ходе игроку нужно действовать так, чтобы минимизировать максимально возможный выигрыш противника.
Выполняя анализ игры, нужно иметь в виду, что каждый игрок придерживается наилучшей стратегии. Чтобы выполнить анализ игры и найти
минимаксную стратегию, можно построить схему, называемую деревом
игры (дерево растет сверху вниз или слева направо). Рассмотрим пример
игры с построением дерева решений.
Двое игроков имеют неограниченное число камней. По правилам игры игроки поочередно кладут по нескольку камней в общую кучу. За
один ход можно положить один камень или удвоить число камней в
куче. Первоначально в куче имеется 2 камня. Выигрывает тот игрок,
после хода которого в куче окажется более 10 камней.
Построим дерево решений, обозначая числами количество камней в
куче после очередного хода. Поскольку игрок может сделать любой из
двух возможных ходов, нужно проверять оба варианта. Если из некоторого
состояния игрок может сделать выигрывающий ход, то другие ходы из
этого состояния рассматривать не нужно.
Удобнее начинать проверку с ходов, которые приводят к большим изменениям кучи. Буквой «в» будем обозначать выигрышный ход игрока, а
буквой «п» – проигрышный.
64
Начальное 1-й
состояние игрок
кучи
2
2*2=4
2+1=3
2-й
игрок
1-й
игрок
4*2=8
4+1=5
8*2=16 в
5*2=10
5+1=6
6*2=12 в
4*2=8
4+1=5
3*2=6
3+1=4
2-й
игрок
1-й
игрок
10*2=20 в
6*2=12 в
8*2=16 в
5*2=10
5+1=6
10*2=20 в
6*2=12 в
Понятно, что выигрышный ход игрока делает предыдущий ход противника проигрышным.
Начальное 1-й
состояние игрок
кучи
2
2*2=4
2+1=3
2-й
игрок
1-й
игрок
4*2=8 п
4+1=5
8*2=16 в
5*2=10 п
5+1=6 п
6*2=12 в
4*2=8 п
4+1=5
3*2=6 п
3+1=4
2-й
игрок
1-й
игрок
10*2=20 в
6*2=12 в
8*2=16 в
5*2=10 п
5+1=6 п
10*2=20 в
6*2=12 в
Если все возможные ходы игрока в определенный момент игры оказались проигрышными, то предыдущий ход противника был выигрышным.
65
Начальное 1-й
состояние игрок
кучи
2
2*2=4
2+1=3
2-й
игрок
1-й
игрок
4*2=8 п
4+1=5 в
8*2=16 в
5*2=10 п
5+1=6 п
6*2=12 в
4*2=8 п
4+1=5 в
3*2=6 п
3+1=4
2-й
игрок
1-й
игрок
10*2=20 в
6*2=12 в
8*2=16 в
5*2=10 п
5+1=6 п
10*2=20 в
6*2=12 в
Если среди возможных ходов игрока в определенный момент игры есть
хотя бы один выигрышный, то предыдущий ход противника был проигрышным.
Начальное 1-й
2-й
состояние игрок
игрок
кучи
2
2*2=4 п 4*2=8 п
4+1=5 в
2+1=3 в 3*2=6 п
3+1=4 п
1-й
игрок
8*2=16 в
5*2=10 п
5+1=6 п
6*2=12 в
4*2=8 п
4+1=5 в
2-й
игрок
1-й
игрок
10*2=20 в
6*2=12 в
8*2=16 в
5*2=10 п
5+1=6 п
10*2=20 в
6*2=12 в
Вывод: выигрывает первый игрок, его первый ход должен быть +1.
C3 (30 мин)
Два игрока играют в следующую игру. На координатной плоскости
стоит фишка. Игроки ходят по очереди. В начале игры фишка находится в
точке с координатами (5,2). Ход состоит в том, что игрок перемещает
фишку из точки с координатами (x,y) в одну из трех точек: или в точку с
координатами (x+3,y), или в точку с координатами (x,y+3), или в точку с
координатами (x,y+4). Выигрывает игрок, после хода которого расстояние
по прямой от фишки до точки с координатами (0,0) не меньше 13 единиц.
66
Кто выигрывает при безошибочной игре обоих игроков – игрок, делающий
первый ход, или игрок, делающий второй ход? Каким должен быть первый
ход выигрывающего игрока? Ответ обоснуйте.
РЕШЕНИЕ
Ответ считается обоснованным, если построено полное дерево игры.
Особо следует обратить внимание на критерий выигрыша – расстояние по
прямой от фишки до точки с координатами (0,0) не меньше 13 единиц.
Это означает, что выигрышным будет попадание фишки в точку с координатами (x, y), для которых выполняется неравенство x2 + y2 >=132 (169).
Дерево игры строится последовательно. Состояния игры могут повторяться на разных ветвях дерева, известные состояния повторно не расписываются.
5,2
1
5,6 п
8,2 п
5,5 п
2
5,10 п
8,6 в
8,6 в
5,9 п
8,5 в
1
5,14 в
8,10 п
11,6 п
8,9 п
5,13 в
8,9 п
11,5 п
8,8 п
2
8,14 в
11,10 в
8,13 в
8,13 в
11,9 в
8,12 в
Выигрывает 2-й игрок. Его первый ход должен быть (8,5) или (8,6).
67
ОГЛАВЛЕНИЕ
1.
Логические задачи ...................... Error! Bookmark not defined.
2.
Основы логики ............................................................................... 7
3.
Системы счисления...................................................................... 15
4.
Кодирование информации .......................................................... 21
5.
Информационные технологии .................................................... 25
6.
Анализ алгоритмов ...................................................................... 31
7.
Разработка алгоритмов ................................................................ 38
8.
Игры двух противников .............................................................. 63
Скачать