Читать книгу 40 задач на Python - - Страница 2
Глава 2: Задачи на числа и арифметику
Оглавление1. Загадка о числовых ребусах
Условие задачи: Для решения числовых ребусов требуется найти, какие буквы представляют собой какие цифры. Каждая буква соответствует уникальной цифре от 0 до 9. Задача состоит в том, чтобы найти такие значения для каждой буквы, чтобы выполнялось правило "одна буква – одна цифра", а также чтобы все равенства в ребусе были верны.
Пример:
Ребус: SEND + MORE = MONEY
Возможное решение: 9567 + 1085 = 10652
Входные данные: Ребус в виде строки, в которой могут быть использованы буквы латинского алфавита в верхнем регистре и знаки арифметических операций (+, -, *, /), а также пробелы.
Выходные данные: Вывести решение ребуса в виде равенства, где буквы заменены на соответствующие им цифры.
Пример:
Входные данные: SEND + MORE = MONEY
Выходные данные: 9567 + 1085 = 10652
Замечание: В решении ребуса необходимо учитывать, что ведущие нули запрещены, и каждая буква соответствует уникальной цифре.
Для решения задачи о числовых ребусах можно использовать метод перебора всех возможных комбинаций цифр для каждой буквы, учитывая правила замены букв на цифры и удовлетворяя условиям ребуса.
План решения:
1. Идентификация уникальных букв: Необходимо определить все уникальные буквы, которые встречаются в ребусе. Это поможет определить количество букв, для которых нужно найти соответствующие им цифры.
2. Перебор всех возможных комбинаций: Для каждой буквы нужно перебрать все возможные цифры от 0 до 9. Можно использовать рекурсивную функцию для генерации всех возможных комбинаций.
3. Проверка условий ребуса: Для каждой комбинации цифр нужно проверить, удовлетворяют ли они условиям ребуса. Например, сумма двух чисел должна давать третье число.
4. Вывод решения: Если найдены цифры, удовлетворяющие условиям ребуса, необходимо вывести их вместе с соответствующими буквами, образуя равенство.
5. Оптимизация: Можно использовать различные оптимизации, такие как исключение неподходящих комбинаций на ранних этапах, чтобы ускорить поиск решения.
Один из возможных способов решения задачи о числовых ребусах на основе предложенного плана:
```python
# Функция для проверки, что цифры в числе уникальны
def are_digits_unique(num):
return len(set(num)) == len(num)
# Функция для решения числового ребуса
def solve_rebus(rebus):
# Извлекаем уникальные буквы из ребуса
unique_chars = set(char for char in rebus if char.isalpha())
# Генерируем все возможные комбинации цифр для уникальных букв
for digits in itertools.permutations('0123456789', len(unique_chars)):
digits_str = ''.join(digits)
# Проверяем, что ведущие нули отсутствуют и цифры уникальны
if digits_str[0] != '0' and are_digits_unique(digits_str):
# Заменяем буквы на соответствующие цифры в ребусе
rebus_with_digits = rebus.translate(str.maketrans({char: digit for char, digit in zip(unique_chars, digits_str)}))
# Разделяем ребус на левую и правую части
left, right = rebus_with_digits.split('=')
# Проверяем, удовлетворяет ли решение ребусу
if eval(left) == eval(right):
return rebus_with_digits
return None
# Пример использования
rebus = "SEND + MORE = MONEY"
solution = solve_rebus(rebus)
if solution:
print(solution)
else:
print("Решение не найдено.")
```
Этот код генерирует все возможные комбинации цифр для уникальных букв в ребусе, заменяет буквы на соответствующие цифры в ребусе и проверяет, удовлетворяет ли полученное выражение условиям ребуса. Если находится решение, оно выводится на экран.
Объяснения к коду:
1. Функция `are_digits_unique`:
– Эта функция принимает строку `num`, представляющую число в виде строки.
– Внутри функции используется `set`, чтобы преобразовать строку в множество уникальных символов.
– Функция возвращает `True`, если количество символов в строке `num` совпадает с количеством уникальных символов, что означает, что все цифры в числе уникальны. В противном случае функция возвращает `False`.
2. Функция `solve_rebus`:
– Эта функция принимает строку `rebus`, представляющую собой числовой ребус.
– Она начинается с извлечения уникальных букв из ребуса с помощью функции `set` и условия `char.isalpha()`. Таким образом, `unique_chars` содержит все уникальные буквы, встречающиеся в ребусе.
– Затем функция перебирает все возможные перестановки цифр от 0 до 9 с помощью функции `itertools.permutations`, указывая количество цифр, соответствующее количеству уникальных букв в ребусе.
– Для каждой перестановки цифр функция проверяет, что ведущий ноль отсутствует, вызывая `digits_str[0] != '0'`, и что все цифры уникальны, вызывая функцию `are_digits_unique`.
– Если эти условия выполнены, функция заменяет буквы на соответствующие цифры в ребусе с помощью метода `str.translate` и словаря, созданного с помощью `zip`.
– Затем ребус разбивается на левую и правую части с помощью метода `split('=')`.
– После этого проверяется, является ли результат левой части равенства (`eval(left)`) равным результату правой части (`eval(right)`).
– Если это так, то функция возвращает ребус с замененными буквами на цифры. Если не найдено ни одного решения, функция возвращает `None`.
3. Пример использования:
– В примере использования задается ребус `"SEND + MORE = MONEY"`.
– Функция `solve_rebus` вызывается с этим ребусом.
– Если найдено решение, оно выводится на экран. Если решение не найдено, выводится сообщение "Решение не найдено."
2. Магические квадраты
Описание задачи: Магический квадрат – это квадратная матрица размером (n \times n), заполненная числами от 1 до (n^2) таким образом, что суммы чисел в каждой строке, каждом столбце и обеих диагоналях равны.
Ваша задача – написать программу, которая проверяет, является ли данная матрица магическим квадратом.
Формат ввода:
– В первой строке задается одно целое число (n) ((1 leq n leq 100)) – размерность матрицы.
– В следующих (n) строках содержится по (n) целых чисел, разделенных пробелами, – элементы матрицы.
Формат вывода:
– Выведите `YES`, если матрица является магическим квадратом.
– Выведите `NO` в противном случае.
Пример 1:
Ввод:
3
8 1 6
3 5 7
4 9 2
Вывод: YES
Пример 2:
Ввод:
3
2 7 6
9 5 1
4 3 8
Вывод: NO
Пример 3:
Ввод:
2
1 2
3 4
Вывод: NO
Решение:
1. Считать размерность матрицы (n) и её элементы.
2. Проверить, что все числа от 1 до (n^2) присутствуют в матрице.
3. Вычислить сумму первой строки (или любого другого ряда) как эталонную сумму.
4. Проверить, что суммы всех строк, столбцов и диагоналей равны эталонной сумме.
5. Вывести результат проверки.
Пример кода на Python:
```python
def is_magic_square(matrix):
n = len(matrix)
# Проверка, что все числа от 1 до n^2 присутствуют
all_numbers = set(range(1, n*n + 1))
numbers_in_matrix = set(num for row in matrix for num in row)
if all_numbers != numbers_in_matrix:
return False
# Вычисление эталонной суммы
magic_sum = sum(matrix[0])
# Проверка строк
for row in matrix:
if sum(row) != magic_sum:
return False
# Проверка столбцов
for col in range(n):
if sum(matrix[row][col] for row in range(n)) != magic_sum:
return False
# Проверка диагоналей
if sum(matrix[i][i] for i in range(n)) != magic_sum:
return False
if sum(matrix[i][n-i-1] for i in range(n)) != magic_sum:
return False
return True
# Чтение данных
n = int(input())
matrix = [list(map(int, input().split())) for _ in range(n)]
# Проверка и вывод результата
if is_magic_square(matrix):
print("YES")
else:
print("NO")
```
Этот код считывает входные данные, проверяет, является ли матрица магическим квадратом, и выводит соответствующий результат.
Подробное объяснение кода проверки магического квадрата
Шаг 1: Считывание размерности матрицы и её элементов
– Код: `n = int(input())`
– Здесь используется функция `input()` для чтения входного значения, представляющего размерность матрицы. Функция `int()` преобразует строку в целое число.
– Код: `matrix = [list(map(int, input().split())) for _ in range(n)]`
– Этот код считывает ( n ) строк, каждая из которых содержит ( n ) чисел.
– `input().split()` считывает строку и разбивает её по пробелам, возвращая список строк.
– `map(int, …)` преобразует каждую строку в целое число.
– `list(…)` собирает эти числа в список.
– Внешний цикл `for _ in range(n)` выполняется ( n ) раз, собирая все строки в список списков (матрицу).
Шаг 2: Проверка уникальности чисел от 1 до ( n^2 )
– Код: `all_numbers = set(range(1, n*n + 1))`
– `range(1, n*n + 1)` создает последовательность чисел от 1 до ( n^2 ).
– `set(…)` преобразует эту последовательность в множество для удобства проверки уникальности.
– Код: `numbers_in_matrix = set(num for row in matrix for num in row)`
– Вложенный генератор `num for row in matrix for num in row` проходит по всем элементам матрицы и собирает их в множество `numbers_in_matrix`.
– Эта строка кода проверяет, что все числа от 1 до ( n^2 ) присутствуют в матрице и являются уникальными.
– Код: `if all_numbers != numbers_in_matrix: return False`
– Сравнение множеств `all_numbers` и `numbers_in_matrix`. Если они не равны, то матрица не может быть магическим квадратом, и функция возвращает `False`.
Шаг 3: Вычисление эталонной суммы
– Код: `magic_sum = sum(matrix[0])`
– `sum(matrix[0])` вычисляет сумму чисел в первой строке матрицы.
– Эта сумма принимается за эталонную, с которой будут сравниваться суммы остальных строк, столбцов и диагоналей.
Шаг 4: Проверка сумм строк
– Код: `for row in matrix: if sum(row) != magic_sum: return False`
– Цикл проходит по каждой строке `row` в матрице.
– `sum(row)` вычисляет сумму чисел в текущей строке.
– Если сумма строки не равна `magic_sum`, функция возвращает `False`.
Шаг 5: Проверка сумм столбцов
– Код: `for col in range(n): if sum(matrix[row][col] for row in range(n)) != magic_sum: return False`
– Внешний цикл проходит по каждому столбцу `col`.
– Внутренний генератор `matrix[row][col] for row in range(n)` собирает все элементы столбца.
– `sum(…)` вычисляет сумму элементов текущего столбца.
– Если сумма столбца не равна `magic_sum`, функция возвращает `False`.
Шаг 6: Проверка сумм диагоналей
– Главная диагональ:
– Код:`if sum(matrix[i][i] for i in range(n)) != magic_sum: return False`
– Генератор `matrix[i][i] for i in range(n)` собирает элементы главной диагонали (где индексы строки и столбца равны).
– `sum(…)` вычисляет сумму этих элементов.
– Если сумма главной диагонали не равна `magic_sum`, функция возвращает `False`.
– Побочная диагональ:
– Код: `if sum(matrix[i][n-i-1] for i in range(n)) != magic_sum: return False`
– Генератор `matrix[i][n-i-1] for i in range(n)` собирает элементы побочной диагонали (где сумма индексов строки и столбца равна \( n-1 \)).
– `sum(…)` вычисляет сумму этих элементов.
– Если сумма побочной диагонали не равна `magic_sum`, функция возвращает `False`.
Шаг 7: Вывод результата
– Код: `if is_magic_square(matrix): print("YES") else: print("NO")`
– Если функция `is_magic_square(matrix)` возвращает `True`, программа выводит "YES".
– В противном случае выводится "NO".
Итог
Код последовательно проверяет все необходимые условия для магического квадрата, от уникальности чисел до сумм строк, столбцов и диагоналей. Если все условия выполняются, матрица признается магическим квадратом.
3. Проблемы с делением и умножением
Описание задачи: Напишите программу, которая будет выполнять деление и умножение двух чисел, но с учетом некоторых специальных случаев.
Условия:
1. Если второе число равно нулю, программа должна вывести сообщение "Ошибка: деление на ноль" и завершиться.
2. Если первое число равно нулю, результатом умножения будет 0, независимо от значения второго числа.
3. Если второе число больше первого, программа должна вывести результат деления в виде десятичной дроби с двумя знаками после запятой.
4. В остальных случаях программа должна выполнять деление и умножение обычным образом.
Формат ввода: Два целых числа, разделенных пробелом: (a) и (b) \((-10^9 leq a, b leq 10^9)).
Формат вывода:
– Если второе число равно нулю, вывести сообщение "Ошибка: деление на ноль".
– В остальных случаях вывести результат деления и умножения, учитывая указанные условия.
Примеры:
Ввод: 5 2
Вывод: 10 2.50
Ввод: 0 7
Вывод: 0 0
Ввод: 4 8
Вывод: 0 0.50
Ввод: 3 0
Вывод: Ошибка: деление на ноль
Примечание:
Результат деления и умножения должен выводиться через пробел в том же порядке, в котором они перечислены в формате вывода.
Идея решения этой задачи включает следующие шаги:
1. Считывание двух целых чисел (a) и (b).
2. Проверка, равно ли второе число нулю. Если да, вывести сообщение об ошибке и завершить программу.
3. Проверка, равно ли первое число нулю. Если да, результат умножения будет 0, иначе обычное умножение.
4. Проверка, больше ли второе число первого. Если да, результат деления будет десятичной дробью, иначе обычное деление.
5. Вывод результатов умножения и деления.
Код, который реализует описанную выше идею:
```python
# Чтение входных данных
a, b = map(int, input().split())
# Проверка деления на ноль и вывод ошибки
if b == 0:
print("Ошибка: деление на ноль")
else:
# Проверка на случай, когда первое число равно нулю
if a == 0:
mul_result = 0
else:
mul_result = a * b
# Проверка на случай, когда второе число больше первого
if b > a:
div_result = "{:.2f}".format(a / b)
else:
div_result = a // b
# Вывод результатов
print(mul_result, div_result)
```
Этот код сначала считывает два целых числа, разделенных пробелом. Затем он проверяет, равно ли второе число нулю. Если да, выводится сообщение об ошибке. В противном случае код проверяет, равно ли первое число нулю, и вычисляет результат умножения. После этого он проверяет, больше ли второе число первого, и в зависимости от этого вычисляет результат деления. Наконец, он выводит оба результата в нужном формате.
Давайте разберем подробно каждую часть кода:
1. Чтение входных данных:
```python
a, b = map(int, input().split())
```
– `input()` считывает строку ввода от пользователя.
– `split()` разделяет эту строку на список строк, используя пробел как разделитель.
– `map(int, …)` применяет функцию `int()` к каждой строке списка, преобразуя их в целые числа.
– `a, b = …` присваивает первое и второе числа переменным `a` и `b`.
2. Проверка деления на ноль:
```python
if b == 0:
print("Ошибка: деление на ноль")
```
– Этот блок кода проверяет, равно ли второе число `b` нулю. Если да, выводится сообщение об ошибке "Ошибка: деление на ноль".
3. Проверка случая, когда первое число равно нулю:
```python
if a == 0:
mul_result = 0
else:
mul_result = a * b
```
– Если первое число `a` равно нулю, результат умножения `mul_result` будет 0, потому что любое число, умноженное на ноль, равно нулю.
– В противном случае, результат умножения будет равен `a * b`.
4. Проверка случая, когда второе число больше первого:
```python
if b > a:
div_result = "{:.2f}".format(a / b)
else:
div_result = a // b
```
– Если второе число `b` больше первого `a`, результат деления `div_result` будет десятичной дробью, округленной до двух знаков после запятой.
– В противном случае, результат деления будет целым числом, полученным с помощью оператора целочисленного деления `//`.
5. Вывод результатов:
```python
print(mul_result, div_result)
```
– Этот код выводит результаты умножения и деления, разделенные пробелом, используя функцию `print()`. Если было выброшено исключение, результат деления не будет выводиться.
В задаче реализован алгоритм, который выполняет умножение и деление двух чисел с учетом специальных случаев. Если второе число равно нулю, программа выводит сообщение об ошибке "Ошибка: деление на ноль". В остальных случаях программа выполняет умножение двух чисел и проверяет несколько условий:
1. Если первое число равно нулю, результат умножения будет 0.
2. Если второе число больше первого, результат деления будет десятичной дробью с двумя знаками после запятой.
3. В остальных случаях программа выполняет деление и умножение обычным образом.
После вычислений программа выводит результаты умножения и деления, разделенные пробелом. Такой подход позволяет корректно обрабатывать различные сценарии, включая случаи деления на ноль и особые случаи с числами равными или различающимися по значению.
4. Задача о двух шляпах и трех числах
Описание задачи: Представьте, что перед вами стоит 3 человека, каждый из которых надевает на себя либо красную, либо синюю шляпу. Они не могут видеть цвет своей собственной шляпы, но видят шляпы других.
Ваша задача – написать программу, которая определяет минимальное количество человек, которые могут быть уверены в цвете своей шляпы.
Условия:
1. У каждого человека есть только два варианта цвета шляпы: красный или синий.
2. Люди могут смотреть только вперед, не знают количество людей за собой и не могут общаться друг с другом.
Формат ввода:
– Три целых числа, разделенных пробелом: (a), (b), (c), где (a), (b), (c) – 0 (красная шляпа) или 1 (синяя шляпа), представляющие цвета шляп каждого человека в порядке их стояния.
Формат вывода:
– Одно целое число, представляющее минимальное количество человек, которые могут быть уверены в цвете своей шляпы.
Примеры:
Ввод: 0 0 1
Вывод: 2
Ввод: 1 1 1
Вывод: 0
Ввод: 0 1 0
Вывод: 3
Примечание: В этой задаче каждый человек смотрит на шляпы тех, кто стоит перед ним. Например, первый человек смотрит на шляпы второго и третьего человека, второй человек смотрит на шляпы третьего человека, а третий человек не видит шляп никого.
Решение: Для решения этой задачи нужно взглянуть на последнего человека в очереди и рассмотреть, сколько человек перед ним надели шляпы того же цвета, что и он.
Если количество человек с шляпами такого же цвета, что и шляпа последнего человека, нечетное, то этот последний человек уверен в цвете своей шляпы. В противном случае, он не может быть уверен в цвете своей шляпы.
Следовательно, мы можем рассматривать только последний человек в очереди, и на основе цвета его шляпы решить, уверен он в своем цвете или нет.
Давайте реализуем этот подход в коде.
```python
def min_people_to_be_certain(a, b, c):
# Подсчет количества людей с шляпами того же цвета, что и шляпа последнего человека
count_same_color = sum([a, b, c]) – max(a, b, c)
# Если количество таких людей нечетное, последний человек уверен в цвете своей шляпы
if count_same_color % 2 != 0:
return 0
else:
return 1
# Чтение входных данных
a, b, c = map(int, input().split())
# Вывод результата
print(min_people_to_be_certain(a, b, c))
```
В этом коде функция `min_people_to_be_certain` принимает три целых числа (a), (b) и (c), представляющих цвета шляп каждого человека в очереди. Она сначала считает количество людей с шляпами того же цвета, что и шляпа последнего человека, а затем проверяет, нечетное ли это число. Если да, то последний человек уверен в цвете своей шляпы, и функция возвращает 0, иначе возвращает 1.
После считывания входных данных программа вызывает эту функцию и выводит результат.
В данной задаче минимальное количество человек, которые могут быть уверены в цвете своей шляпы, зависит от того, сколько человек перед последним надели шляпы того же цвета, что и он сам.
Если количество людей с шляпами такого же цвета, что и шляпа последнего человека, нечетное, то последний человек уверен в цвете своей шляпы, так как он видит нечетное количество шляп такого же цвета, как у него.
Если количество людей с шляпами такого же цвета, что и шляпа последнего человека, четное, то последний человек не может быть уверен в цвете своей шляпы, так как он видит четное количество шляп такого же цвета, как у него.
Таким образом, ответ на задачу зависит только от количества людей с шляпами того же цвета, что и шляпа последнего человека. Если это количество нечетное, то минимальное количество людей, которые могут быть уверены в цвете своей шляпы, равно 0, иначе 1.
Вывод программы представляет собой это минимальное количество человек, которые могут быть уверены в цвете своей шляпы.
5. Числовые последовательности и их секреты
Описание задачи: Представьте, что перед вами задача – найти секрет в числовой последовательности. Ваша задача – написать программу, которая будет искать этот секрет в последовательности чисел.
Условия:
1. В числовой последовательности может быть скрыт секрет, который представляет собой подпоследовательность чисел, образующих определенный узор.
2. Секрет может быть разным: это может быть арифметическая прогрессия, геометрическая прогрессия или какой-то другой узор.
Формат ввода:
– Последовательность целых чисел, разделенных пробелом.
Формат вывода:
– Описание найденного секрета в виде строки, например, "Арифметическая прогрессия с разностью 3", "Геометрическая прогрессия с множителем 2", или "Нет секрета".
Примеры:
Ввод: 1 3 5 7 9
Вывод: Арифметическая прогрессия с разностью 2
Ввод: 2 4 8 16 32
Вывод: Геометрическая прогрессия с множителем 2
Ввод: 1 2 4 7 11
Вывод: Нет секрета
Примечание: В этой задаче ваша программа должна определить, является ли найденный узор арифметической прогрессией, геометрической прогрессией или если в последовательности нет никакого узора.
Для решения этой задачи нужно пройти по всей последовательности чисел и проверить, является ли она арифметической прогрессией, геометрической прогрессией или не содержит никакого узора.