
Преобразование логических выражений
Штана Альберт Игоревич
В этой статье будет разобрано задание 15.
Рассмотрим типовые задачи из пятнадцатого задания ЕГЭ по информатике.
Данное задание относится к повышенному уровню сложности.
Время выполнения задания ≈ 3 минуты.
Данный тип задач проверяет знания основных понятий и законов математической логики.
Про основы алгебры логики ссылка на статью.
Какое количество натуральных чисел удовлетворяет логическому условию:
k = 0
for x in range(1, 1000):
if not(x**2 >= 9) or not((x < 7) or (x >= 10)):
k += 1
print(k)
Заводим переменную счётчик в которой будет ответ. Перебираем с помощью цикла for натуральные числа от 1 до 1000 (можно и меньше 1000, но лучше проверить больший диапазон чисел). Внутри цикла пропишем после оператора if логическое выражение. Если логическое вернуло True (истина), то подсчитываем такой вариант в переменную счётчика. В конце работы цикла выводим на консоль ответ на задачу: значение переменной счётчика.
Ответ: 5
Задача очень проста. Рассмотрим далее другие варианты и посложнее.
Для какого наибольшего целого неотрицательного числа A выражение:
mx = 0
for A in range(0, 100):
k = 0
for X in range(1, 301):
for Y in range(1, 301):
if (X >= A) or (Y >= A) or (X * Y <= 205):
k += 1
if k == 300 * 300:
mx = max(mx, A)
print(mx)
Ответ: 15
Обозначим через DEL(n, m) утверждение «натуральное число n делится без остатка на натуральное число m». Для какого наибольшего натурального числа А формула:
def dl(n, m):
if n % m == 0:
return True
return False
mx = 0
for A in range(1, 100):
k = 0
for X in range(1, 1001):
if dl(X, A) or (not (dl(X, 6)) or not (dl(X, 9))):
k += 1
if k == 1000:
mx = max(mx, A)
print(mx)
Здесь решение аналогично прошлой задаче за некоторым изменением. Вначале нужно задать функцию dl которая будет проверять утверждение «натуральное число n делится без остатка на натуральное число m». Далее в циклах "прокрутим" значения для A и для X. Внутри цикла для X делаем проверку условия из выражения с вызовами функции DEL (dl). После цикла for для X и внутри цикла for для A нужно проверить счётчик. Значение в переменной счётчика k должно совпадать с количеством запусков цикла for для X если это так — вычисляем максимум. После тогда как перебрали циклами все значения для A и для X — выводим значение переменной максимума mx в консоль как ответ на задачу.
Ответ: 18
Обозначим через m&n поразрядную конъюнкцию неотрицательных целых чисел m и n. Например:
for A in range(0, 100):
k = 0
for X in range(0, 1000):
if X & 51 == 0 or (X & A != 0 or X & 25 != 0):
k += 1
if k == 1000:
print(A)
break # Как только нашли ответ — выходим из цикла
Циклами перебираем значения для A и для X. A, и X — неотрицательные числа поэтому перебираем их диапазон, начиная с нуля. Не забываем, при проверке выражения в условии if, преобразовывать операцию следование. После отработки цикла for для X проверяем чтобы в переменной счётчика k было значение равное количеству запусков цикла для переменной X. Так как циклы начинаются с нуля то как только условие проверки по счётчику будет пройдено — это и будет минимальное A. Выводим ответ на задачу и прерываем цикл.
Ответ: 34
На числовой прямой даны отрезки P=[5, 13] и Q=[8, 19].
Укажите наименьшую возможную длину такого отрезка A, что формула:
def f(a, b, x):
if a <= x <= b:
return True
return False
mn = 10 ** 9
for a in range(0, 100):
for b in range(a, 100):
k = 0
for i in range(1, 200):
x = i / 2
if not (f(5, 13, x) or f(8, 19, x)) or f(a, b, x):
k += 1
if k == 199:
mn = min(mn, b - a)
print(mn)
Сначала напишем функцию *f, которая будет проверять принадлежность точки x к отрезку [a, b]. Заводим переменную mn в которую будем записывать вычисление минимального отрезка A. A — это отрезок и его значения мы перебираем с помощью двух циклов for для возможных значений a и для b. Внутри циклов для каждого отрезка A заводим переменную счётчик k. В задачах на отрезки нужно, чтобы переменная x перебиралась как дробное число. Для этого используем вспомогательный цикл for с i. _Отрезок A перебираем с нуля, а цикл i начинаем перебирать с 1 из-за исключительной ситуации с нулями. Диапазон range цикла i создаём примерно в два раза больше по сравнению с циклом a. И внутри этого цикла получаем переменную x = i/2. Таким образом, диапазон для переменной x будет примерно таким же, как и для переменной a, только шаг у переменной x - 0,5. Затем подсчитываем в счётчик k, сколько раз выполнится логическая функция. После цикла i, проверяем счёт k. Если при каждом проходе цикла, логическая функция выдавала истину, то отрезок A подходит. В ответе нужно написать минимальную длину отрезка. Используем функцию min, чтобы найти минимальный отрезок.
Ответ: 14
На числовой прямой даны два отрезка: P = [43; 49] и Q = [44; 53]. Укажите наибольшую возможную длину такого отрезка A, что формула:
def f(a, b, x):
if a <= x <= b:
return True
return False
def fa(a, b, x):
if a < x < b:
return True
return False
mx = 0
for a in range(0, 100):
for b in range(a, 100):
k = 0
for i in range(1, 200):
x = i / 2
if (not (fa(a, b, x)) or f(43, 49, x)) or f(44, 53, x):
k += 1
if k == 199:
mx = max(mx, b - a)
print(mx)
При поиске отрезка максимальной длины, нужно создать функцию fa со строгим неравенством и её применять только к отрезку A.
Ответ: 10
Обозначим через ДЕЛ(n, m) утверждение «натуральное число n делится без остатка на натуральное число m». Пусть на числовой прямой дан отрезок B = [70, 90]. Для какого наибольшего натурального числа А логическое выражение ДЕЛ(x, А) ∨ ((x ∈ B) → ¬ДЕЛ(x, 22)) истинно (т.е. принимает значение 1) при любом целом положительном значении переменной х?
def dl(n, m):
if n % m == 0:
return True
return False
def f(a, b, x):
if a <= x <= b:
return True
return False
mx = 0
for A in range(1, 200):
k = 0
for x in range(1, 201):
if dl(x, A) or (not (f(70, 90, x)) or not (dl(x, 22))):
k += 1
if k == 200:
mx = max(mx, A)
print(mx)
Задача гибрид в которой деление и есть элементы задания на отрезки. Искомая переменная A - это обычное число, не отрезок. Логика решения задачи такая же как в прошлых задачах.
Ответ: 88
Для какого наименьшего целого неотрицательного числа A выражение:
for A in range(0, 200):
k = 0
for x in range(0, 200):
for y in range(0, 200):
if (x + 2*y < A) or (y > x) or (x > 60):
k += 1
if k == 200*200:
print(A)
break
В цикле перебираем все возможные значения A, а затем также в двух циклах перебираем значения x, y. Т.к. в задании говорится про целые неотрицательные числа и в ответ нужно указать число A значит оно будет в первом цикле перебираться сначала, а потом уже все x и y. Изначально стоит выбирать небольшие значения для циклов например 20, 50, 100, 150. Я нашёл решение только когда прописал диапазон до 200(функция range). В 3 цикле с y проверяем само выражение(если бы в задаче спрашивали про ложность, то необходимо было всё выражение взять в скобочки и инвертировать через not). И последнее в условии в цикле для A проверяем в конце то что x, y были любыми целыми числами(два цикла по 200, результат счётчика 200*200). Если это так, то выводим ответ на задачу и прерываем цикл, чтобы программа быстрее завершилась и не "перебирала" дальше.
Ответ: 181
На числовой прямой даны два отрезка: P = [15; 40] и Q = [21; 63].
Укажите наименьшую возможную длину такого отрезка A, для которого логическое выражение:
answer = 9999999999999
for a in range(0, 100):
for b in range(a, 100):
counter = 0
for i in range(2, 200):
x = i / 2
if not (15 <= x <= 40) or (not (21 <= x <= 63 and not (a <= x <= b)) or not (15 <= x <= 40)):
counter += 1
if counter == 198:
answer = min(answer, b - a)
break
print(answer)
Ответ: 19
На числовой прямой даны два отрезка: P = [25; 64] и Q = [40; 115].
Укажите наименьшую возможную длину такого отрезка A, для которого логическое выражение:
answer = 9999999999999
for a in range(0, 100):
for b in range(a, 100):
counter = 0
for i in range(2, 200):
x = i / 2
if not (25 <= x <= 64) or (not (40 <= x <= 115 and not (a <= x <= b)) or not (25 <= x <= 64)):
counter += 1
if counter == 198:
answer = min(answer, b - a)
break
print(answer)
Ответ: 24
Попробуйте сами запустить код в окне ниже с интерпретатором Python и повторите примеры из статьи чтобы самим увидеть и понять как всё это работает. Для этого в ячейке с кодом нажмите клавиши на клавиатуре Shift+Enter или запустите код через кнопку Run по значку ▶.