Разбор домашних заданий

Разбор задач

'Логарифм'

К. О. как бы подсказывает нам, что вся задача сводится к вычислению логарифма по основанию 10.

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

Отформатируем спойлер, разбив его по действиям:

Для Y из диапазона 1/100…1000 x не может быть меньше -2 или больше 3.

Начнем с x1=-2 и x2=3. Найдём середину этого диапазона, M = 0.5.

Если 10**0.5<Y, значит ответ лежит в диапазоне от 0.5 до 3,
а если 10**0.5⩾Y — в диапазоне от -2 до 0.5.
Соответственно переназначим границы диапазона x1 и x2
и снова проверим новую середину M.
Если 10**M<Y, ответ лежит между M и x2,
а если 10**M⩾Y — между x1 и M.
Будем повторять это последнее действие до тех пор,
пока размер диапазона x2-x1 не окажется меньше 0.0000001.

Начнём переводить с русского на Python (с «» начинаются т. н. комментарии, при виде которых Python игнорирует оставшийся конец строки. В комментарии можно писать что угодно!):

   1 # Не забудем ввести Y
   2 Y = float(input())
   3 
   4 # Для Y из диапазона 1/100…1000 x не может быть меньше -2 или больше 3.
   5 x1, x2 = -2, 3
   6 
   7 # Начнем с x1=-2 и x2=3. Найдём середину этого диапазона, M = 0.5.
   8 M = 0.5
   9 
  10 # Соответственно переназначим границы диапазона x1 и x2
  11 # Если 10**0.5<Y, значит ответ лежит в диапазоне от 0.5 до 3,
  12 if 10 ** 0.5 < Y:
  13     x1, x2 = 0.5, 3
  14 # а если 10**0.5⩾Y — в диапазоне от -2 до 0.5.
  15 else:
  16     x1, x2 = -2, 0.5
  17 
  18 # и снова проверим новую середину M.
  19 # Если 10**M<Y, ответ лежит между M и x2,
  20 # а если 10**M⩾Y — между x1 и M.
  21 # Будем повторять это последнее действие до тех пор,
  22 # пока размер диапазона x2-x1 не окажется меньше 0.0000001.

Можно было сразу формулировать алгоритм про x1 , x2 и M:

   1 # Не забудем ввести Y
   2 Y = float(input())
   3 
   4 # Для Y из диапазона 1/100…1000 x не может быть меньше -2 или больше 3.
   5 x1, x2 = -2, 3
   6 
   7 # Начнем с x1=-2 и x2=3. Найдём середину этого диапазона, M = 0.5.
   8 M = x1 + (x2 - x1) / 2
   9 
  10 # Соответственно переназначим границы диапазона x1 и x2
  11 # Если 10**M<Y, ответ лежит между M и x2,
  12 if 10 ** 0.5 < Y:
  13     x1 = M
  14 # а если 10**M⩾Y — между x1 и M.
  15 else:
  16      x2 = M
  17 
  18 # Будем повторять это последнее действие до тех пор,
  19 # пока размер диапазона x2-x1 не окажется меньше 0.0000001.

Часть алгоритма (начинающуюся с if …) нужно выполнять много раз, пока x1 не приблизится к x2. В Python проверка условия пишется в начале цикла:

   1 # Не забудем ввести Y
   2 Y = float(input())
   3 
   4 # Для Y из диапазона 1/100…1000 x не может быть меньше -2 или больше 3.
   5 x1, x2 = -2, 3
   6 
   7 # Начнем с x1=-2 и x2=3. Найдём середину этого диапазона, M = 0.5.
   8 M = x1 + (x2 - x1) / 2
   9 
  10 # Будем повторять это последнее действие до тех пор,
  11 # пока размер диапазона x2-x1 не окажется меньше 0.0000001.
  12 while x2 - x1 >= 1e-7:
  13     # Если 10**M<Y, ответ лежит между M и x2,
  14     if 10 ** M < Y:
  15         x1 = M
  16     # а если 10**M⩾Y — между x1 и M.
  17     else:
  18         x2 = M
  19 
  20 print(M)

Программа теперь запускается, но молчит и не останавливается! Можем поставить в конце цикла отладочную выдачу, чтобы посмотреть, чему равны наши переменные

   1 # Не забудем ввести Y
   2 Y = float(input())
   3 
   4 # Для Y из диапазона 1/100…1000 x не может быть меньше -2 или больше 3.
   5 x1, x2 = -2, 3
   6 
   7 # Начнем с x1=-2 и x2=3. Найдём середину этого диапазона, M = 0.5.
   8 M = x1 + (x2 - x1) / 2
   9 
  10 # Будем повторять это последнее действие до тех пор,
  11 # пока размер диапазона x2-x1 не окажется меньше 0.0000001.
  12 while x2 - x1 >= 1e-7:
  13     # Если 10**M<Y, ответ лежит между M и x2,
  14     if 10 ** M < Y:
  15         x1 = M
  16     # а если 10**M⩾Y — между x1 и M.
  17     else:
  18         x2 = M
  19     print(x1, x2, M)
  20 print(M)

Оказывается, мы не вполне правильно отформатировали спойлер (или зря удалили фразу «снова проверим новую середину»). Стартовые значения x1 и x2 должны определяться в начале программы, а вот M — середина отрезка — вычисляться заново внутри цикла:

   1 # Не забудем ввести Y
   2 Y = float(input())
   3 
   4 # Для Y из диапазона 1/100…1000 x не может быть меньше -2 или больше 3.
   5 # Начнем с x1=-2 и x2=3.
   6 x1, x2 = -2, 3
   7 
   8 # Будем повторять это последнее действие до тех пор,
   9 # пока размер диапазона x2-x1 не окажется меньше 0.0000001.
  10 while x2 - x1 >= 1e-7:
  11     # Найдём середину этого диапазона, M
  12     M = x1 + (x2 - x1) / 2
  13 
  14     # Если 10**M<Y, ответ лежит между M и x2,
  15     if 10 ** M < Y:
  16         x1 = M
  17     # а если 10**M⩾Y — между x1 и M.
  18     else:
  19         x2 = M
  20 print(M)

Эта программа работает!

Python/GeoPython2021/04_Loops/Prac2 (последним исправлял пользователь FrBrGeorge 2021-10-08 12:22:52)