дотщд. Ялдыгин В. Б., 2021 03. 11. 2021 Как работать над пособием Основные правила
Скачать 1.41 Mb.
|
if n == 64: print(i, n) Теперь s и n выводятся только тогда, когда получается n=64. Поскольку строки значения s и n выводятся только тогда, когда получается n=64, во всех строках вторым значением (это n) выведено 64. Получается, n нет смысла выводить (оно выводится всегда одинаковое. Изменим программу for i in range(1, 1_001): s = i s = s // 10 n = 1 while s < 51: s = s + 5 n = n * 2 if n == 64: 48 © Ялдыгин В.Б., 2021 03.11.2021 print(i, n) print(i) Теперь выводятся только s, при которых получается n=64: Кстати, теперь, когда программа не выводит лишнего, она работает гораздо быстрее, а экран не засорен, лишними строками. Можно поменять программу, чтобы она проверяла значения не от 1 до 1.000, а, скажем, от 1 до миллиона (1.000.000), чтобы точно проверить всевозможные подходящие значения for i in range(1, 1_001): for i in range(1, 1_000_001): s = i s = s // 10 n = 1 while s < 51: s = s + 5 n = n * 2 if n == 64: print(i) Это и есть оптимальная программа. Нона будущее нужно разобрать пару важных вопросов. В программе i пробегает от 1 до миллиона (1.000.000). Возникает вопрос можно ли перебирать значения, скажем, до триллиона (1.000.000.000.000), чтобы совсем точно проверить все значения И вообще как определить, до какого значения может пробегать i? Самый простой способ – просто попробовать. Если программа завершилась достаточно быстро, значит, все нормально (и можно даже подумать о том, чтобы увеличить диапазон пробегаемых чисел. Если же программа какое-то время не завершается, возможно, указали слишком большой диапазон и стоит уменьшить второе число. 49 © Ялдыгин В.Б., 2021 03.11.2021 Как определить, что программа завершилась Во том, что программа завершилась, можно судить потому, что появилось приглашение (>>>). Рассмотрим на практике. Запустим программу с первой строкой for i in range(1, 1_000_001). Совсем скоро программа завершится ив появится приглашение (показано красной стрелкой Значит, от 1 до миллиона программа перебирает значения достаточно быстро (и для данной задачи пробегать значения до миллиона – более чем достаточно. Для опыта попробуем указать значение гораздо больше. Закроем Shell крестиком (в следующий раз при запуске программы он откроется, причем в нем не будет результатов прошлых запусков, что удобно. Теперь изменим первую строку, чтобы i пробегало от 1 до триллиона (1.000.000.000.000) и программа выполнялась долго for i in range(1, 1_000_000_000_001). Некоторое время спустя приглашение все еще не появилось значит, программа еще выполняется Попробуем закрыть Shell. Будет выдано следующее сообщение Приглашение Приглашение не появилось, значит, программа еще выполняется 50 © Ялдыгин В.Б., 2021 03.11.2021 Перевод Программа все еще выполняется Вы хотите завершить ее) Нажимаем OK, программа завершится и Shell закроется. Попробуйте проделать описанное выше сами, чтобы подобное сообщение не стало для вас неожиданностью Поэкспериментируйте с различными значениями второго числа в range. Как мы увидели, до миллиона программа выполняется достаточно быстро, до триллиона – долго (даже ждать не стоит. За какое время у вас выполнится программа, если i будет пробегать от 1 до 100 миллионов (100.000.000)? Результат зависит от быстродействия вашего компьютера, например, намоем ноутбуке программа выполняется примерно за 20 секунд. Разберем еще одно изменение в программе, которое для данной задачи не требуется, но пригодится в будущем. Сейчас программа выводит значения в порядке возрастания, поскольку i пробегает значения от 1 до 1.000.000 по возрастанию. Последним выводится число 259 (максимальное из подходящих, окно до него автоматически проматывается, а нам как раз нужно найти максимальное подходящее число. Если бы требовалось найти минимальное число (в данной задаче 210), потребовалось бы перемотать экран вверх до первого выведенного числа. Это несложно. Тем не менее, если написать программу так, чтобы числа выводились по убыванию, то число 210 будет выведено последними нам бы не потребуется перематывать экран вверх. Изменим цикл for, чтобы i пробегало значения от 1.000.000 до 1 по убыванию. Такой цикл запишется так for i in range(1_000_000, 0, -1). Поясним кратко подробная информация есть в разделе Цикл for»). Третий аргумент – шаг. Сейчас он -1, значит, каждое следующее число на 1 меньше предыдущего (если третий аргумент не указан, как в прошлых программах, он равен 1, то есть каждое следующее число на 1 больше предыдущего. Как обычно, i пробегает от первого значения (1.000.000) до второго (0), не доходя до него, то есть от 1.000.000 до 1, что нами нужно. Получилась такая программа for i in range(1, 1_000_001): for i in range(1_000_000, 0, -1): s = i s = s // 10 n = 1 51 © Ялдыгин В.Б., 2021 03.11.2021 while s < 51: s = s + 5 n = n * 2 if n == 64: print(i) Теперь подходящие значения s выводятся по убыванию, и последним выведено минимальное значение Резюмируем. Вот исходная программа (измененные нами в дальнейшем строки выделены жирным синим шрифтом и зачеркнуты s = int(input()) s = s // 10 n = 1 while s < 51: s = s + 5 n = n * 2 print(n) Вот измененная программа (добавленная строка выделена черным жирным шрифтом, а новые варианты строк, отмеченных выше синим, также написаны жирным синим шрифтом, но уже не зачеркнуты for i in range(1, 1_000_001): s = i s = s // 10 n = 1 while s < 51: s = s + 5 n = n * 2 if n == 64: print(i) 52 © Ялдыгин В.Б., 2021 03.11.2021 Дополнение. Если программа будет работать долго, можно уменьшить 1_000_001, скажем, до 100_001. Теоретическое решение и решения в Excel, намой взгляд, менее удобны. Вы можете посмотреть их в файле Полякова. Задание 22 Повышенный уровень сложности, примерное время выполнения – 7 минут. Намой взгляд, задание примерно того же уровня сложности, что и задание 6, то есть рекомендую исходить из того, что уровень сложности задания – базовый. Следовательно, данное задание, как и остальные задания базового уровня сложности, обязательно нужно уметь решать. При разборе задания 22 используются наработки, полученные при разборе задания 6, поэтому разбор задания менее подробный. В связи с этим вначале убедитесь, что вы хорошо знаете материал по решению задания 6 и при необходимости повторите. До того, как читать разбор задания, попробуйте решить задание аналогично тому, как решалось задание 6, и только затем прочитайте разбор задания. 2022-22 Получив на вход число x, этот алгоритм печатает два числа L и M. Укажите наибольшее число x, при вводе которого алгоритм печатает сначала 4, а потом 5. x = int(input()) Q = 9 L = 0 while x >= Q: L = L + 1 x = x - Q M = x if M < L: M = L L = x print(L) print(M) Автоматический перебор с помощью программы Скопируем программу в IDLE, сделаем отступ табуляцией x = int(input()) Q = 9 L = 0 while x >= Q: 53 © Ялдыгин В.Б., 2021 03.11.2021 L = L + 1 x = x - Q M = x if M < L: M = L L = x print(L) print(M) Добавим первой строкой цикл for, в котором переменная i будет пробегать от 1 до 10.001. Важно вначале у меня, как ив программе в задании 6, i пробегало до миллиона (1.000.000, 1_000_001 в range), но программа быстро не завершилась. Я попробовал изменить значение на 100 тысяч (100.000, 100_001 в range), но программа все еще работало долго. И только когда я указал 10 тысяч (10.000, 10_001 в range), программа стала работать быстро. for i in range(1, 10_001): x = int(input()) Q = 9 L = 0 while x >= Q: L = L + 1 x = x - Q M = x if M < L: M = L L = x print(L) print(M) Внесем изменения, чтобы переменная x получала значение нес клавиатуры, а из переменной s: for i in range(1, 10_001): x = int(input()) x = i Q = 9 L = 0 while x >= Q: L = L + 1 x = x - Q 54 © Ялдыгин В.Б., 2021 03.11.2021 M = x if M < L: M = L L = x print(L) print(M) Необходимо вывести значения x, при которых алгоритм печатает сначала 4, а потом 5. По тексту программы видно, что она вначале выводит L, затем M. Выводи для 1.000.000 значений x будет очень неудобен. Заменим выводи на проверку что L=4 и M=5. Если это выполнено, то будем выводить начальное значение x (выводить сам x смысла нет, так в процессе выполнения алгоритма оно меняется, но начальное значение, которое было присвоено переменной x, не меняется, – это значение i). Итак, чтобы вывести начальное значение x, нужно вывести i! for i in range(1, 10_001): x = i Q = 9 L = 0 while x >= Q: L = L + 1 x = x - Q M = x if M < L: M = L L = x print(L) print(M) if L == 4 and M == 5: print(i) Будет выведено 2 числа 41 и 49. Нам нужно максимальное, значит, ответ 49. Резюмируем. Вот исходная программа (измененные нами в дальнейшем строки выделены жирным синим шрифтом и зачеркнуты x = int(input()) Q = 9 L = 0 while x >= Q: L = L + 1 55 © Ялдыгин В.Б., 2021 03.11.2021 x = x - Q M = x if M < L: M = L L = x print(L) print(M) Вот измененная программа (добавленная строка выделена черным жирным шрифтом, а новые варианты строк, отмеченных выше синим, также написаны жирным синим шрифтом, но уже не зачеркнуты for i in range(1, 10_001): x = i Q = 9 L = 0 while x >= Q: L = L + 1 x = x - Q M = x if M < L: M = L L = x if L == 4 and M == 5: print(i) |