Главная страница
Навигация по странице:

  • Задача 17: Постфиксная запись

  • Задача 19: Личные дела

  • Задача 20: Скидки

  • Задача 21: Двоичный поиск

  • Задача 22: Корень кубического уравнения

  • Задача 23: k-кузнечик

  • Задача 24: Калькулятор

  • основы_программирования_на_языке_python. Министерство образования и науки российской федерации федеральное государственное бюджетное образовательное учреждение высшего


    Скачать 208.8 Kb.
    НазваниеМинистерство образования и науки российской федерации федеральное государственное бюджетное образовательное учреждение высшего
    Дата01.02.2022
    Размер208.8 Kb.
    Формат файлаdocx
    Имя файлаосновы_программирования_на_языке_python.docx
    ТипКурсовая
    #348377
    страница4 из 8
    1   2   3   4   5   6   7   8

    Задача 16: Медиана списка

    Ограничение по времени работы программы: 1 секунда

    Дан список целых чисел. Найдите в нем “медианный” элемент, то есть то число, которое будет ровно посередине списка, если список отсортировать.

    ВХОДНЫЕ ДАННЫЕ

    Программа получает на вход n целых чисел, записанных через пробел в одной строке, 1≤n≤100, значение n — нечетное. Сами числа по модулю не превосходят 109

    ВЫХОДНЫЕ ДАННЫЕ

    Программа должна вывести одно число — медианный элемент данного списка.

    ПРИМЕР

    ввод

    вывод

    2 8 1 5 4

    4

    РЕШЕНИЕ

    Считаем файл, создадим список из считанных чисел. Отсортируем его при помощи любого из алгоритмов сортировки. Выведем элемент с индексом n//2.

    def InsertionSort(A):
        for i in range(1, len(A)):
            new_elem = A[i]
            j = i - 1
            while j >= 0 and A[j] > new_elem:
                A[j + 1] = A[j]
                j -= 1
            A[j + 1] = new_elem

    A = list(map(int, input().split()))
    InsertionSort(A)
    print(A[len(A) // 2])


    Задача 17: Постфиксная запись

    Ограничение по времени работы программы: 1 секунда

    В постфиксной записи (или обратной польской записи) операция записывается после двух операндов.

    Например, сумма двух чисел A+B записывается как «A B + ». Запись «B C + D * » обозначает привычное нам (B+C)*D, а запись «A B C + D * + » означает A+(B+C)*D.

    Достоинство постфиксной записи в том, что она не требует скобок и дополнительных соглашений о приоритете операторов для своего чтения.

    Дано выражение в обратной польской записи. Определите его значение.

    ВХОДНЫЕ ДАННЫЕ

    В единственной строке записано выражение в постфиксной записи, содержащее однозначные числа и операции +, −, *.

    Строка содержит не более 100 чисел и операций.

    ВЫХОДНЫЕ ДАННЫЕ

    Необходимо вывести значение записанного выражения.

    Гарантируется, что результат выражения, а также результаты всех промежуточных вычислений по модулю меньше 231.

    ПРИМЕР

    ввод

    вывод

    8 9 + 1 7 - *

    -102

    РЕШЕНИЕ

    Обратная польская запись — это по сути последовательность действий над стеком.

    Заведем стек. Считываем входные данные. Если очередной элемент — это число (символ от «0» до «9»), то добавим его в стек. Если это операция — то извлечем из стека два последних элемента, применим к ним данную операцию и положим результат в стек.

    В конце выведем единственное число, которое будет находиться в стеке.

    stack = []

    for elem in input().split():

        if elem in '+-*':

            a = stack[-2]

            b = stack[-1]

            stack.pop()

            stack.pop()

            if elem == '+':

                result = a + b

            elif elem == '-':

                result = a - b

            else:

                result = a * b

            stack.append(result)

        else:

            stack.append(int(elem))

    print(stack[0])

    Задача 18: Правильная скобочная последовательность

    Ограничение по времени работы программы: 1 секунда

    Требуется определить, является ли правильной данная последовательность круглых, квадратных и фигурных скобок.

    ВХОДНЫЕ ДАННЫЕ

    В единственной строке входных данных записано подряд N скобок (1≤N≤105).

    ВЫХОДНЫЕ ДАННЫЕ

    Выведите «YES», если данная последовательность является правильной, и «NO» в противном случае.

    ПРИМЕР

    ввод

    вывод

    ()

    YES

    ([])

    YES

    ([)]

    NO

    РЕШЕНИЕ

    Задача решается с использованием стека. Заведем стек. Открывающиеся скобки кладем в стек. Если встречается закрывающаяся скобка, то проверяем, соответствует ли она скобке на вершине стека, если соответствует — удалим из стека верхнюю скобку, если нет — то последовательность неправильная.

    В конце работы алгоритма стек должен остаться пустым.

    Типичные ошибки:

    1. При удалении скобки из стека не проверяется, что стек не пуст.

    2. Не проверяется, что в конце работы алгоритма стек пуст.

    3. Неправильная проверка скобок на парность (это удобно сделать отдельной функцией IsPair).

    import sys

    import sys

    Stack = []

    def IsPair(left, right):

        return left + right in ["()", "[]", "{}"]

     

    for bracket in input():

        if bracket in '([{':

            Stack.append(bracket)

        else:

            if len(Stack) == 0:

                print("NO")

                sys.exit(0)

            if not IsPair(Stack.pop(), bracket):

                print("NO")

                sys.exit(0)

                

    if len(Stack) == 0:

        print('YES')

    else:

        print('NO')

    Задача 19: Личные дела

    Ограничение по времени работы программы: 1 секунда

    Однажды, неловкая секретарша перепутала личные дела учащихся. Теперь их снова необходимо упорядочить сначала по классам, а внутри класса по фамилиям.

    ВХОДНЫЕ ДАННЫЕ

    В первой строке входных данных записано число N (1≤N≤1000) – количество личных дел. Далее записано N строк, каждая из которых состоит из фамилии учащегося (строка без пробелов) и номера класса (целое число от 1 до 11).

    ВЫХОДНЫЕ ДАННЫЕ

    Нужно вывести список всех учащихся, сначала выводя номер класса, затем — фамилию учащегося. Список должен быть отсортирован по классу, а затем по фамилии.

    ПРИМЕР

    ввод

    вывод

    3
    Ivanov 10
    Petrov 9
    Sidorov 9

    9 Petrov
    9 Sidorov
    10 Ivanov

    РЕШЕНИЕ

    Необходимо отсортировать личные дела, которые представляют собой пару из класса и фамилии. Удобно так и хранить информацию о личных делах — в виде кортежа из двух элементов. Если создать список, элементами которого будут кортежи из номера класса и фамилии, то стандартная сортировка их отсортирует правильно. Кортежи сравниваются в лексикографическом порядке — то есть сначала по первому полю, а если они равны — то по второму полю и т. д.

    n = int(input())
    A = []
    for i in range(n):
        name, form = input().split()
        A.append( (int(form), name) )
    A.sort()
    for elem in A:
        print(elem[0], elem[1])


    Задача 20: Скидки

    Ограничение по времени работы программы: 1 секунда

    В супермаркете проводится беспрецедентная акция — “Покупая два любых товара, третий получаешь бесплатно*”, а внизу мелким шрифтом приписано “* - из трех выбранных вами товаров оплачиваются два наиболее дорогих”.

    Вася, идя в супермаркет, определился, какие товары он хочет купить, и узнал, сколько они стоят. Помогите ему определить минимальную сумму денег, которую ему нужно взять с собой, чтобы в итоге стать счастливым обладателем этих товаров.

    ВХОДНЫЕ ДАННЫЕ

    Программа получает на вход число N (1≤N≤1000), а затем N чисел — стоимости выбранных Васей товаров. Все стоимости — натуральные числа, не превышающие 10000.

    ВЫХОДНЫЕ ДАННЫЕ

    Выведите одно число — сумму денег, которую Вася должен взять с собой в супермаркет (минимально возможную).
    ПРИМЕР

    ввод

    вывод

    Примечание

    6
    1 5 4 3 5 7

    19

    Вася сначала пройдет через кассу с товарами стоимостью 1, 3 и 4 – заплатит 7 рублей и товар стоимостью 1 получит в подарок, а затем снова зайдет в супермаркет и купит товары стоимостью 5 и 7, еще один товар стоимостью 5 получив в подарок.

    5
    3 15 25 8 8

    51

    Вася в первый заход в супермаркет купит товары стоимостью 15 и 25 рублей, в качестве подарка взяв товар стоимостью 8 рублей. А во второй заход в супермаркет купит товары стоимостью 3 и 8, не взяв никакого подарка.

    РЕШЕНИЕ

    Сначала отсортируем список всех товаров, которые хочет приобрести Вася.

    Теперь будем выбирать товары в порядке убывания стоимости. Два самых дорогих товара Вася должен приобрести, после чего третий по стоимости товар он получит бесплатно. Далее продолжим, пока не будут перебраны все товары.

    В приведенном ниже решении используются срезы для выбора тех товаров, которые оплатит Вася.

    n = int(input())
    A = list(map(int, input().split()))
    A.sort(reverse=True)
    print(sum(A[::3]) + sum(A[1::3]))


    Задача 21: Двоичный поиск

    Ограничение по времени работы программы: 2 секунды

    Даны два списка чисел. В первом списке содержится N чисел, отсортированных по не убыванию. Во втором списке находится M других чисел. Для каждого числа из второго списка найдите его первое и последнее вхождение в первый список.

    ВХОДНЫЕ ДАННЫЕ

    В первой строке входных данных записано N упорядоченных по не убыванию целых неотрицательных чисел — элементы первого списка.

    Во второй строке записаны M целых неотрицательных чисел.

    Количество чисел в каждом списке не превосходит 20.000.

    ВЫХОДНЫЕ ДАННЫЕ

    Программа должна вывести M строчек. Для каждого числа из второго списка нужно вывести индекс его первого и последнего вхождения в первый список. Если число не входит в первый список, нужно вывести одно число −1.

    ПРИМЕР

    ввод

    вывод

    1 1 3 3 5 7 9 18 18 57
    57 3 9 1 179

    9 9
    2 3
    6 6
    0 1
    -1

    РЕШЕНИЕ

    Считаем первый список A. Переберем в переменной key все элементы второго списка.

    Для каждого элемента key второго списка вызовем функции UpperBound и LowerBound, запишем их результат в переменные upper и lower. Проверим, есть ли элемент key в списке A (например, по условию lower < len(A) and A[lower] == key). Если есть — выведем lower и upper - 1, иначе выведем -1.

    def UpperBound(A, key):
        left = -1
        right = len(A)
        while right - left > 1:
            middle = (left + right) // 2
            if A[middle] <= key:
                left = middle
            else:
                right = middle
        return right

    def LowerBound(A, key):
        left = -1
        right = len(A)
        while right - left > 1:
            middle = (left + right) // 2
            if A[middle] < key:
                left = middle
            else:
                right = middle
        return right

    A = list(map(int, input().split()))
    for key in input().split():
        key = int(key)
        lower = LowerBound(A, key)
        upper = UpperBound(A, key)
        if lower < len(A) and A[lower] == key:
            print(lower, upper - 1)
        else:
            print(-1)


    Задача 22: Корень кубического уравнения

    Ограничение по времени работы программы: 1 секунда

    Дано кубическое уравнение ax3+bx2+cx+d=0 (a≠0). Известно, что у этого уравнения ровно один корень. Требуется его найти с точностью до 10−4.

    ВХОДНЫЕ ДАННЫЕ

    Программа получает на вход четыре целых числа a, b, c, d, по модулю не превосходящие 1000, a≠0. Числа записаны в одной строке через пробел.

    ВЫХОДНЫЕ ДАННЫЕ

    Выведите единственный корень уравнения с точностью до 10−4 (то есть ваш ответ должен отличаться от правильного не больше, чем на 10−4).

    ПРИМЕР

    ввод

    вывод

    1 -3 3 -1

    0.999999598818135

    -1 -6 -12 -7

    -0.999999999990564

    РЕШЕНИЕ

    Будем использовать вещественный двоичный поиск — рассмотрим интервал, на концах которого функция имеет разные знаки, будем сокращать интервал в два раза, пока его длина не станет меньше, чем 10−4. Необходимо правильно изолировать корни — выбрать начальный интервал так, чтобы значение функции было разных знаков на концах этого интервала. В качестве такого интервала можно взять [−2000,2000]. Также необходимо рассмотреть два случая - a>0 и a<0. Они отличаются знаками функции на концах интервала. Проще всего свести второй случай к первому, умножив все коэффициенты на -1.

    EPS = 0.0000001

    def f(x):
        return a * x ** 3 + b * x ** 2 + c * x + d

    def root():
        left = -2000
        right = 2000
        while right - left > EPS :
            middle = (right + left) / 2
            if f(middle) > 0:
                right = middle
            else :
                left = middle
        return (left + right) / 2

    a, b, c, d = map(float, input().split())

    if a < 0:
        a = -a
        b = -b
        c = -c
        d = -d

    print(root())


    Задача 23: k-кузнечик

    Ограничение по времени работы программы: 1 секунда

    Кузнечик умеет прыгать на расстояние 1, 2, … , k клеток (то есть длина прыжка кузнечика не превышает k). Определите, каким числом способов кузнечик может попасть из точки 0 в точку n.

    ВХОДНЫЕ ДАННЫЕ

    Программа получает на вход два числа, записанных в одной строке — n и k (0≤n≤30, 1≤k≤10).

    ВЫХОДНЫЕ ДАННЫЕ

    Программа должна вывести одно число — искомое количество способов.

    ПРИМЕР

    ввод

    вывод

    7 2

    21

    РЕШЕНИЕ

    Воспользуемся динамическим программированием. Целевая функция: F(i) — количество способов попасть в точку номер i. Рекуррентное соотношение: F[i]=F[i−k]+F[i−k+1]+…+F[i−1]. Начальное значение - F[0]=0. Необходимо также аккуратно обработать случай вычисления F(i), когда i
    n, k = map(int, input().split())

    F = [0 ] * (n + 1)

    F[0 ] = 1

    for i in range(1, n + 1):

        F[i] = sum(F[max(0, i - k):i])

    print(F[n])

    Задача 24: Калькулятор

    Ограничение по времени работы программы: 4 секунды

    Исполнитель «Калькулятор» может с заданным числом X выполнить одну из трех операций и получить новое число. Возможные операции:

    Прибавить к числу X единицу.

    Умножить число X на 2.

    Умножить число X на 3.

    Определите, какое наименьшее число операций необходимо для того, чтобы получить из числа 1 заданное число N.

    ВХОДНЫЕ ДАННЫЕ

    Программа получает на вход одно число N, не превосходящее 106.

    ВЫХОДНЫЕ ДАННЫЕ

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

    ПРИМЕР

    ввод

    вывод

    1

    0

    5

    3

    962340

    17

    РЕШЕНИЕ

    Решим задачу методом динамического программирования. Целевая функция: F(i) — наименьшее число операций, при помощи которых можно получить число i. Число i можно получить за одну операцию из числа i−1, i/2 (для языка Pascal i div 2) (если i делится на 2) и i/3 (для языка Pascal i div 2) (если i делится на 3). Рекуррентное соотношение — F[i]=min(F[i−1],F[i/2],F[i/3])+1 (для языка Pascal: F[i] = min(F[i-1], F[i div 2], F[i div 3]) + 1), при этом значение F[i/2] (для языка Pascal F[i div 2]) нужно учитывать, только если i делится на 2, а значение F[i/3] (для языка Pascal F[i div 3]) — только если i делится на 3. Начальное значение — F[1]=0.

    N = int(input())

    F = [0 ] * (N + 1)

    F[1 ] = 0

    for i in range(2, N + 1):

        F[i] = F[i - 1]

        if i % 2 == 0 and F[i // 2] < F[i]:

            F[i] = F[i // 2]

        if i % 3 == 0 and F[i // 3] < F[i]:

            F[i] = F[i // 3]

        F[i] += 1

    print(F[N])
    1   2   3   4   5   6   7   8


    написать администратору сайта