## Решения задач с КЗН (Файл: `КЗН_ИНФОРМАТИКА_май 2023.docx`)
**№1.** Найдите все пятизначные числа, которые при делении на 133 дают в остатке 125, а при делении на 134 дают в остатке 111.
**Решение:**
```Python
for i in range(10_000, 99_999):
if i % 133 == 125 and i % 134 == 111:
print(i)
```
**№2.** Натуральное число называется числом Армстронга, если сумма цифр числа, возведенных в N-ную степень (где N – количество цифр в числе) равна самому числу. Например, 153 = $ 1^3 + 5^3 + 3^3 $. Найдите все трёхзначные Армстронга.
**Решение:**
```Python
print("3-x значные числа Армстронга:")
for i in range(100, 999):
s = 0
n = i
while n > 0:
decimal = n%10
s += decimal**3
n //= 10
if s == i:
print(i)
```
**№3.** Натуральное число называется автоморфным, если оно равно последним цифрам своего квадрата. Например, 252 = 625. Напишите программу, которая получает натуральное число N и выводит на экран все автоморфные числа, не превосходящие N.
**Решение:**
```Python
print("Введите N:")
n = int(input())
for i in range(1, n):
num = str(i)
num2 = str(i**2)
if num2[-len(num)::] == num: # см. слайсы
print(f"{num}*{num}={num2}")
```
**№4.** Напишите программу, которая получает два целых числа A и B (0 < A < B) и выводит квадраты всех натуральных чисел в интервале от A до B.
**Решение:**
```Python
print("Введите два целых числа:")
a, b = input().split(" ")
a, b = int(a), int(b)
for i in range(a, b+1):
print(f"{i}*{i}={i**2}")
```
**№5.** Напишите программу, которая получает два целых числа и находит их произведение, не используя операцию умножения. Учтите, что числа могут быть отрицательными.
##### Пример:
```
Введите два числа:
10 -15
10*(-15)=-150
```
**Решение:**
```Python
print("Введите два целых числа:")
a, b = input().split(" ")
a, b = int(a), int(b)
if b == 0:
res = 0
else:
res = int( a/(1/b) )
if b >= 0:
print(f"{a}*{b}={res}")
else:
print(f"{a}*({b})={res}")
```
№6 (не будет на КЗН). Ввести натуральное число N и вычислить сумму всех чисел Фибоначчи, меньших N. Предусмотрите защиту от ввода отрицательного числа N.
##### Пример:
```
Введите число N:
10000
Сумма 17709
```
**Решение:**
```Python
n = int(input("Введите число N: "))
if n <= 0:
print("Программа принимает только натуральное число N")
exit(0)
f1, f2 = 1, 2
s = 0
while f1 < n:
s += f1
f1, f2 = f2, f1+f2
print("Сумма", s)
```
№7 (не будет на КЗН). Дано натуральное число n. Вычислить:
$$
(1 + \frac {1} {1^2})*(1 + \frac {1} {2^2}) * ... * (1 + \frac {1} {n^2})
$$
**Решение:**
```Python
n = int(input("Введите число N: "))
if n <= 0:
print("Программа принимает только натуральные числа N")
exit(0)
m = 1
for i in range(1, n+1):
m *= (1 + 1/i**2)
print(f"Произведение: {m}")
```
**№8.** Ввести натуральное число и найти сумму его цифр.
##### Пример:
```
Введите натуральное число:
12345
Сумма цифр 15.
```
**Решение:**
```Python
n = int(input("Введите число N: "))
s = 0
while n > 0:
digit = n % 10
s += digit
n //= 10
print("Сумма цифр", s)
```
**№9.** Ввести натуральное число и определить, верно ли, что в его записи есть две одинаковые цифры, стоящие рядом.
##### Пример:
```
Введите натуральное число:
12342
Нет.
```
##### Пример:
```
Введите натуральное число:
12245
Да.
```
**Решение:**
```Python
n = input("Введите натуральное число: ")
for i in range(1, len(n)):
if n[i] == n[i-1]:
print("Да.")
break # Выходим из цикла
else: # Выполнится, если цикл завершился без break
print("Нет.")
```
**№10.** Ввести натуральное число и определить, верно ли, что в его записи есть две одинаковые цифры (необязательно стоящие рядом).
##### Пример:
```
Введите натуральное число:
12342
Да.
```
##### Пример:
```
Введите натуральное число:
12345
Нет.
```
**Решение:**
```Python
n = input("Введите натуральное число: ")
digits = []
unique_digits = set()
for digit in n:
"""
Добавляем элементы в список digits и множество unique_digits.
Последнее содержит только уникальные элементы, в отличии от списка.
Следовательно, если есть повторяющиеся числа, значит количество элементов в списке
и множетсве будет различным.
"""
digits.append(digit)
unique_digits.add(digit)
if len(digits) != len(unique_digits):
print("Да.")
else:
print("Нет.")
```
## Решение задач из файла `Задания_олимпиады_инф.docx`
**1.** Для детей решили вырезать разные геометрические фигуры: круг, треугольник, квадрат. Каждой фигуры по одной. Сколько останется бумаги по площади после обрезки. Считается, что все фигуры можно вырезать на листе бумаге размером AxB. Для каждой фигуры даны соответствующие параметры: для круга - радиус, для квадрата и треугольника равностороннего - длина стороны.
##### Формат ввода
В первой строке вводятся через пробел ввод два натуральных числа А и В - стороны листа. Далее в следующей строке через пробел вводятся три натуральных числа: радиус круга, сторона квадрата и сторона равностороннего треугольника соответственно. Все числа не превосходят $10^6$.
##### Формат вывода
Выводится одно вещественное число с точностью до двух знаков после запятой - ответ на задачу.
##### Пример:
| Ввод | Вывод |
| ------ | ------ |
| 5 6
1 2 3 | 18.96 |
**Решение:**
```Python
from math import pi, sqrt
a, b = input().split(" ")
r, f, h = input().split(" ")
a, b, r, f, h = int(a), int(b), int(r), int(f), int(h)
paperSquare = a*b
rectSquare = f**2
circleSquare = r**2*pi
triangleSquare = (h**2*sqrt(3))/4
result = round(paperSquare-circleSquare-rectSquare-triangleSquare, 2)
print(result)
```
**2.** Красивое число делится на 7 и не содержит повторяющихся цифр, например, 21 - красивое число, а 77 - нет. Найти на заданном отрезке все красивые числа. Если таких чисел нет, то вывести сообщение "NO".
###### Формат ввода
Вводятся два натуральных числа: начало и конец отрезка. Все числа не превосходят $10^6$.
###### Формат вывода
Если счастливые числа существуют, то вывести их через пробел, иначе - вывести сообщение "NO".
| Ввод | Вывод |
| ------ | ------ |
| 5 20 | 7 14 |
**Решение:**
```Python
a, b = input().split(" ")
a, b = int(a), int(b)
def isPrettyNumber(n):
digits = [i for i in str(n)]
unique_digits = set(digits)
return n % 7 == 0 and len(digits) == len(unique_digits)
existPrettyNumbers = False
for i in range(a, b+1):
if isPrettyNumber(i):
print(i, end=" ")
existPrettyNumbers = True
if not existPrettyNumbers:
print("NO")
else:
print()
```
**3.** Рыбаки поймали карпа, карася, ерша и т.д. Не все смогли выловить весь набор рыб. Каждому хочется отнести домой один и тот же комплект рыб. Смогут ли они это сделать, если собрать каждого вида рыб и разделить поровну? Учтите, что рыбы должны быть целыми.
###### Формат ввода
В первой строке вводится через пробел N количество рыбаков и P количество наименований рыб. Каждое число не превосходит 10 000. Далее в каждой N-ой строке записаны P чисел - количество рыб соответствующих наименований (от 0 до $10^9$).
###### Формат вывода
На первой строке вывести "Yes", если это возможно и далее на второй строке соответствующее количество рыб каждого наименования через пробел. Если это не возможно, то вывести "No".
##### Пример:
| Ввод | Вывод |
| --- | --- |
| 3 2
12 6
0 8
3 1 | Yes
5 5 |
**Решение:**
```Python
fishersmen, categories = input().split(" ")
fishersmen, categories = int(fishersmen), int(categories)
fish = [0 for _ in range(categories)] # Заполняем массив нулями
# [0, 0, 0, ... P]
for i in range(fishersmen):
# Ниже собираем сколько каждого вида рыбы поймал рыбак
# Это список вида [8, 4, 6, ... P]
collectedFish = input().split(" ")
# Ниже преобразуем каждый элемент списка из строки в число
collectedFish = [int(i) for i in collectedFish]
# Прибавляем количесво пойманной рыбы каждого вида к списку fish
for j, fishAmount in enumerate(collectedFish):
fish[j] += fishAmount
# Далее просто проверяем делится ли количество пойманной рыбы нацело
# на количество рыбаков
canDivide = True
for i in fish:
if i % fishersmen != 0:
canDivide = False
if canDivide:
print("Yes")
fishAmount = [str(i//fishersmen) for i in fish]
print(" ".join(fishAmount))
else:
print("No")
```
## Теория
#### Определения
* **Язык** — средство кодирования; это система знаков и правил для записи и передачи информации.
* **Код** — правило, по которому сообщение преобразуется в цепочку знаков.
* **Кодирование** — представление информации в форме, пригодной для её хранения, передачи, автоматизированной обработки.
* **Алфавит** — это набор знаков, который используется в языке.
* **Мощность алфавита** — количество знаков в алфавите. Вычисляется по формуле $N=2^i$
* **Естественные языки** — языки на которых говорят люди.
* **Формальные языки** — язык в котором однозначно определяется значение каждого слова, а также правила построения предложения и предания смысла.
* **Позиционная система счисления** — система счисления, в которой значение цифры определяется её позицией в записи числа.
* **Алфавит с.с.** — используемый в ней набор цифр.
* **Основание с. с.** = N
* **Разряд** — позиция цифры в записи числа.
* **Непозиционная с. с.** — такая с. с., в которой значение цифры не зависит от её места в записи числа. Например, римская сс. (Для справки: L = 50, C = 100, D = 500, M = 1000).
* **Сообщение** — любая последовательность сиволов некоторого алфавита.
* **Равномерный код** — код, в котором все кодовые слова имеют одинаковую длину.
* **Декадирование** — процесс восстановления сообщения из кода.
* **Электронная таблица** — это программа, которая хранит данные в аиде таблиц и автоматически пересчитывает результаты по введенным формулам при изменении этих данных.
* **Редактирование** — изменение данных и структуры таблицы.
* **Форматирование** — изменение внешнего вида таблицы.
#### Формулы
$N = 2^i$ – мощность алфавита, где i - информационный вес символа
$I = ki$ – информационный объём, где k - количество символов в сообщении, i - информационный вес символа. Обычно i принимают за 8 бит, если он не определен в задаче.
Пример использования:
**Задача 1**: Сообщение, записанное буквами из 16-символьного алфавита,
содержит 9000 символов. Какой объем информации оно несет? Ответ
запишите в килобайтах.
**Решение**: Мощность алфавита из условий задачи равна 16, следовательно $N = 2^4$, откуда $i = 4$ (бит). Тогда $I = ki = 9000*4$ = 36000 бит = 4500 байт = 4.39453125 Кбайт.
**Ответ**: 4.39453125 Кбайт.