Задание 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 – заменяем пары на суммы их квадратов и находим максимальную сумму.


Последнее изменение: Понедельник, 22 мая 2023, 19:21