Задание 17
Задание 17 (демо-2023). В файле содержится последовательность целых чисел. Элементы последовательности могут принимать целые значения от –10 000 до 10 000 включительно. Определите количество пар последовательности, в которых только одно число оканчивается на 3, а сумма квадратов элементов пары не меньше квадрата максимального элемента последовательности, оканчивающегося на 3. В ответе запишите два числа: сначала количество найденных пар, затем максимальную из сумм квадратов элементов таких пар. В данной задаче под парой подразумевается два идущих подряд элемента последовательности.
Решение задания на языках PascalABC.NET и Python приведено ниже.
PascalABC.NET |
## var F:=ReadLines('17.txt').Select(s->s.ToInteger); var Max_elem:=F.Where(x->x mod 10 = 3).Max; var (count,max):=(0,0); foreach var (x,y) in F.pairwise do begin if ((abs(x) mod 10 = 3)<>(abs(y) mod 10 =3)) and (x**2+y**2>=Max_elem**2) then begin count+=1; if x*x+y*y >=max then max:=x*x+y*y; end; end; print(count,max) |
Python |
f=list(map(int,open('17.txt'))) Max_elem=0 for i in f: if i>=Max_elem and i%10==3: Max_elem=i count=Max=0 for i in range(len(f)-1): if (abs(f[i])%10==3) != (abs(f[i+1])%10==3) and f[i]**2+f[i+1]**2>=Max_elem**2: count+=1 if f[i]**2+f[i+1]**2>=Max: Max=f[i]**2+f[i+1]**2
print(count,Max) |
Так как данные находятся в файле, то необходимо открыть файл внутри программы и считать данные в переменную. В Python для этого применяется уже стандартная конструкция list(map(int,open('файл.txt'))), которая открывает файл, преобразует строки полученного списка в целые числа функцией int с помощью функции map, а затем результат помещается в новый список функцией list.
В PascalABC.NET задачу можно решить намного проще и нагляднее. Используем функцию ReadAllLines('файл.txt'), с помощью которой считываем все строки в файле, этим мы считываем все числа в переменную F. После этого сразу применяем запрос Select(s->s.ToInteger), который каждую строку преобразует в целое число с помощью метода .ToInteger. Понятность имён функций и последовательность применения запросов делает код, написанный на PascalABC.NET, более понятным и легко повторяемым.
Далее можно сразу найти максимальный элемент, у которого последняя цифра равна трём. В Python это также можно сделать функциональным стилем, но результат будет выходить слишком нагромождённым из-за не сильно удобного синтаксиса лямбда-функций. В PascalABC.NET применим фильтр Where для отбора тех элементов, которые имеют цифру 3 в конце, и сразу после этого функция Max находит максимальный из них: решение получается в одну строку, в то время как в Python – четыре строки.
Чтобы сформировать всевозможные пары соседних чисел, используем функцию Pairwise(). В цикле foreach будем пробегать по всем парам (x,y) из последовательности пар F.Pairwise и проверять условие «только одно число оканчивается на 3» следующим образом: окончание числа x цифрой 3 не должно равняться окончанию числа y на число 3, то есть (abs(x) mod 10 = 3)<>(abs(y) mod 10 =3). Также берётся модуль числа, потому что при взятии остатка от деления на 10 у отрицательного числа не получается последняя цифра числа. В этом же условии проверяем сумму квадратов пары чисел, чтобы одна была не меньше квадрата максимального числа, найденного ранее.
Если такая пара нашлась, то увеличиваем счётчик количества count на один и находим максимальную сумму квадратов пары Max. В ответе выводим пару чисел count и Max.
В PascalABC.NET мы использовали один цикл, в Python использовали два цикла. Однако на PascalABC.NET, с помощью функционального стиля и модуля SF можно ещё более коротко записать решение, представленное ниже.
PascalABC.NET и модуль SF |
### var F:=ReadLines('17.txt').Select(s->StrToInt(s)); var Max2:=F.Wh(x->x mod 10 = 3).Max; var T:=F.Pairwise.Wh(\(x,y)->((abs(x) mod 10 =3)<>(abs(y) mod 10=3)) and (x*x+y*y>=Max2*Max2));
print(T.Cnt,T.Sel(\(x,y)->x*x+y*y).Max); |
Первые строки решения аналогичны обычному решению. Цикл foreach с условиями заменим на цепочку методов и запросов. Pairwise даёт пары чисел, запрос Wh (Where) отбирает пары, удовлетворяющие условию задачи, полученные пары заносим в переменную T.
Функцией print() выводим два значения: T.Cnt (Count) – количество пар, T.Sel(\(x,y)->x*x+y*y).Max – заменяем пары на суммы их квадратов и находим максимальную сумму.