104 подписчика

Примеры решения задач на Python (списки, вложенные списки, срезы, sort, open, close) ч.2

856 прочитали

В статье рассматриваются решения задач, в которых отрабатываются навыки использования списков, срезов, цикла FOR in range, чтение из файла и запись в файл.

фото с сайта https://www.wallpaperflare.com
фото с сайта https://www.wallpaperflare.com

Количество победителей по классам.

В олимпиаде приняло участие N школьников. Каждый получил разное количество баллов. Данные участников задаются в файле в формате: "Фамилия НомерКласса Балл".

Условие очень похоже на задачу "Результаты олимпиады" из предыдущей статьи. Но в этой задаче нужно вывести три числа: количество победителей по 9 классу, по 10 классу, по 11 классу.

inFile = open('input.txt', 'r', encoding='utf8')
scoreQuan = [[0, 0], [0, 0], [0, 0]]
for
line in inFile:
....
line1 = line.split()
....
cl = int(line1[2])
....
sc = int(line1[3])
....if
sc > scoreQuan[cl - 9][0]:
........
scoreQuan[cl - 9][0] = sc
........scoreQuan[cl - 9][1] = 1
....elif sc == scoreQuan[cl - 9][0]:
........
scoreQuan[cl - 9][1] += 1
inFile.close
()
print(scoreQuan[0][1], scoreQuan[1][1], scoreQuan[2][1])

Здесь создаем список scoreQuan, в котором для каждого класса записываем в свой маленький вложенный список в формате: (Балл, Количество_победителей).

Проходной балл.

Каждый абитуриент, при поступлении в вуз, должен предъявить результаты трех экзаменов ЕГЭ. Каждый экзамен оценивается числом от 0 до 100. Если соискатель набрал менее 40 баллов по любому экзамену, то он выбывает из конкурса. Остальные принимают участие в конкурсе по сумме баллов за все три экзамена.

N - количество участников, K - количество мест. Определите проходной балл - минимальный балл, который набрал абитуриент, прошедший по конкурсу. Результаты экзаменов записаны в файле input.txt, который имеет формат: "Фамилия Имя Балл1 Балл2 Балл3".

Если проходят все абитуриенты, у которых нет баллов ниже 40, программа должна вывести число 0.

Если число абитуриентов с равным максимальным баллом больше чем K, программа должна вывести число 1.

Результаты работы программы нужно записать в файл output.txt.

inFile = open('input.txt', 'r', encoding='utf8')
outFile = open('output.txt', 'w', encoding='utf8')
score = []
i = 0
nstr
= 1
for line in inFile:
....if
nstr == 1:
........
k = int(line)
....else:
........
line1 = line.split()
........
sc3 = int(line1[-1])
........
sc2 = int(line1[-2])
........
sc1 = int(line1[-3])
........if
sc1 >= 40 and sc2 >= 40 and sc3 >= 40:
............
score.append(sc1 + sc2 + sc3)
............
i += 1
....nstr += 1
inFile.close
()
if
k >= i:
....
print(0, file=outFile)
else:
....
score.sort(reverse=True)
....if
score[k-1] > score[k]:
........
print(score[k-1], file=outFile)
....else:
........
ans = ''
........for
ii in score[k-1::-1]:
............if
score[k-1] < ii and ans == '':
................
ans = ii
........if ans == '':
............
ans = 1
........print(ans, file=outFile)
outFile.close()

Сначала записываем всех участников, у которых нет оценок ниже 40 баллов, в список score с общей суммой баллов. Если элементов больше, чем число абитуриентов, то сортирует score в обратном порядке. Далее смотрим если условие if score[k-1] > score[k], выполняется, то берем score[k-1], так как score[k], это уже на одно место больше чем K. Проблемы возникают, если score[k-1] == score[k]. Приходится делать цикл в обратном порядке, чтобы найти элемент, который больше score[k] и он будет проходным баллом. Этот индекс записывается в ans, если такой не найден, то ответ будет 1.

Школы с наибольшим числом участников олимпиады.

В олимпиаде по информатике принимало участие N человек. Найдите номера школ, из которых было больше всего участников. Результаты олимпиады записаны в файле input.txt, который имеет формат: "Фамилия Имя НомерШколы Балл". Номер школы — целое число от 1 до 99. Балл — целое число от 0 до 100.

Необходимо вывести номера школ в порядке возрастания номеров.

SchoolList = [0] * 100
inFile
= open('input.txt', 'r', encoding='utf8')
for
line in inFile:
....
line1 = line.split()
....
SchoolList[int(line1[-2])] += 1
inFile.close
()
maxZn = 1
maxIn
= []
ind = 0
for i in SchoolList:
....if
maxZn < i:
........
maxZn = i
........maxIn.clear()
........
maxIn.append(ind)
....elif
maxZn == i:
........
maxIn.append(ind)
....
ind += 1
print
(*maxIn)

Так как номера школ не могут быть больше 100, то для решения задачи можно воспользоваться приемом из алгоритма "Сортировка подсчетом". Создаем список SchoolList с нулевыми значениями и потом в цикле по строкам файла наращиваем счетчики номеров школ, получается список, индексы которого номер школы, а значение - сколько раз встретился этот номер в файле.

Затем в цикле по SchoolList ищем максимальное значение и записываем его индекс в список maxIn. Список maxIn нужен, так как школ с одинаковым максимальным значением может быть несколько. Список maxIn уже будет отсортирован в порядке возрастания номеров школ.

Максимальный балл не-победителя.

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

Найдите максимальный балл для каждого класса того школьника, который не стал победителем в данном классе. Результаты зачетов записаны в файле input.txt, который имеет формат: "Фамилия Имя НомерШколы Балл".

max1 = [0] * 3
max2
= [0] * 3
inFile
= open('input.txt', 'r', encoding='utf8')
for
line in inFile:
....
score = int(line.split()[-1])
....
nclass = int(line.split()[-2])
....if
score > max1[nclass - 9]:
........
max2[nclass - 9], max1[nclass - 9] = max1[nclass - 9], score
....elif score > max2[nclass - 9] and score < max1[nclass - 9]:
........
max2[nclass - 9] = score
inFile.close
()
print(*max2)

Задача сводится к тому, чтобы найти второй максимум в каждом классе, то есть можно в список max1 писать максимумы по классам, а в список max2 - следующий максимум.

Такси.

После долгого совещания директор организации решил развезти сотрудников по домам на такси. Он заказал N машин по числу своих сотрудников. Когда такси подъехали, оказалось, что у каждого водителя свой тариф за 1 километр.

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

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

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

km = list(map(int, input().split()))
cost = list(map(int, input().split()))
km.sort()
cost.sort(reverse=True)
totSum = 0
for i in range(len(km)):
....
totSum = totSum + (km[i] * cost[i])
print(totSum)

Чтобы найти наименьшую сумму нужно самые дорогие тарифы использовать на самые короткие расстояния.

Семипроцентный барьер.

В Госдуму РФ выборы производятся по партийным спискам. Для прохождения в ГД партии должны набрать не менее 7% от числа голосов избирателей.

В файле input.txt введен список партий и список голосов избирателей. Выведите список партий, прошедших семипроцентный барьер.

В первой строке файла с данными написано слово PARTIES:. После этого слова идет список партий, которые участвовали в выборах.

Далее идет строка, в которой записано слово VOTES:. За ним идут названия партий, за которые отдали свои голоса избиратели, по одному названию в строке.

Необходимо вывести названия партий, набравших не менее 7% голосов. Порядок вывода партий должен быть таким же как в первом списке.

partyNames = []
voters = []
totalStr = 0
totalQuan
= 0
names
= ''
inFile = open('input.txt', 'r', encoding='utf8')
for
line in inFile:
....
line = line.rstrip()
....if
totalStr > 0 and names == '' and line != 'VOTES:':
........
partyNames.append(line)
........
voters.append(0)
....if
line == 'VOTES:':
........
names = 1
....elif names == 1:
........
voters[partyNames.index(line)] += 1
........totalQuan += 1
....totalStr += 1
inFile.close
()
ind = 0
for i in voters:
....if
i >= totalQuan/100*7:
....
print(partyNames[ind])
....
ind += 1

Сначала записываем все названия партий в список partyNames. Затем в списке голосов voters наращиваем счетчики тех позиций, индексы которых соответствуют индексам партий в списке partyNames: voters[partyNames.index(line)] += 1.

Потом идем по voters и если число не меньше 7%, то печатаем название партии из partyNames, находя его по индексу из voters.

Упорядочить список партий по числу голосов.

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

partyList = []
totalStr = 0
names
= ''
inFile = open('input.txt', 'r', encoding='utf8')
for
line in inFile:
....
line = line.rstrip()
....if
totalStr > 0 and names == '' and line != 'VOTES:':
........
partyList.append([0, line])
....if
line == 'VOTES:':
........
names = 1
....elif names == 1:
........for
i in range(len(partyList)):
............if
partyList[i][1] == line:
................
partyList[i][0] += 1
....totalStr += 1
inFile.close
()
partyList.sort(key=lambda x: (-x[0], x[1]))
for
i in range(len(partyList)):
....
print(partyList[i][1])

Записываем все названия партий в список partyList, для каждой партии свой вложенный список формата ["ЧислоГолосов, НазваниеПартии]. При прохождении списка голосов для каждого голоса ищем партию и наращиваем счетчик:

............if partyList[i][1] == line:
................
partyList[i][0] += 1

В конце сортируем список partyList с помощью лямбда-функции, которая сортирует по двум параметрам: количеству голосов и внутри по названиям партий.

Всем успехов в программировании!

не много улыбки в статье Айтишный юмор!