Задания
Версия для печати и копирования в MS Word

Име­ет­ся набор дан­ных, со­сто­я­щий из троек по­ло­жи­тель­ных целых чисел. Не­об­хо­ди­мо вы­брать из каж­дой трой­ки ровно одно число так, чтобы сумма всех вы­бран­ных чисел не де­ли­лась на k  =  109 и при этом была мак­си­маль­но воз­мож­ной. Га­ран­ти­ру­ет­ся, что ис­ко­мую сумму по­лу­чить можно. Про­грам­ма долж­на на­пе­ча­тать одно число  — мак­си­маль­но воз­мож­ную сумму, со­от­вет­ству­ю­щую усло­ви­ям за­да­чи.

Вход­ные дан­ные.

Файл A

Файл B

Даны два вход­ных файла (файл A и файл B), каж­дый из ко­то­рых со­дер­жит в пер­вой стро­ке ко­ли­че­ство троек N (1 ≤ N ≤ 1 000 000). Каж­дая из сле­ду­ю­щих N строк со­дер­жит три на­ту­раль­ных числа, не пре­вы­ша­ю­щих 20 000.

При­мер ор­га­ни­за­ции ис­ход­ных дан­ных во вход­ном файле:

6

1 3 7

5 12 6

6 9 11

5 4 8

3 5 4

1 1 1

Для ука­зан­ных вход­ных дан­ных, в слу­чае, если k  =  5, зна­че­ни­ем ис­ко­мой суммы яв­ля­ет­ся число 44.

В от­ве­те ука­жи­те два числа: сна­ча­ла зна­че­ние ис­ко­мой суммы для файла А, затем для файла B.

 

Ответ:

Спрятать решение

Ре­ше­ние.

Будем по­сле­до­ва­тель­но счи­ты­вать трой­ки чисел из файла и при­бав­лять к пе­ре­мен­ной sum мак­си­маль­ное число в трой­ке. Также будем на­хо­дить ми­ни­маль­ную раз­ни­цу между мак­си­маль­ным чис­лом в трой­ке и ми­ни­маль­ным чис­лом в трой­ке, между мак­си­маль­ным чис­лом в трой­ке и сред­ним по зна­че­нию чис­лом в трой­ке. Раз­ни­ца между чис­ла­ми при этом не долж­на де­лить­ся на 109 без остат­ка. В конце вы­пол­не­ния про­грам­мы будем про­ве­рять, де­лит­ся ли най­ден­ная сумма на 109 без остат­ка, и если не де­лит­ся  — будем вы­во­дить най­ден­ную сумму, иначе будем вы­во­дить най­ден­ную сумму, вычтя из неё най­ден­ную ми­ни­маль­ную раз­ни­цу между чис­ла­ми.

 

При­ведём ре­ше­ние за­да­чи на языке Pascal.

var

x, y, z: integer;

n: integer;

sum: int64;

minDif: integer;

f: text;

begin

assign(f,'C:\27_B.txt');

reset(f);

readln(f, n);

sum := 0;

minDif := 40001;

while not eof(f) do begin

readln(f, x, y, z);

if (x >= y) and (x >= z) then begin

sum := sum + x;

if (((abs(x - y)) mod 109 <> 0) and (abs(x - y) < minDif)) then

minDif := abs(x - y);

if (((abs(x - z)) mod 109 <> 0) and (abs(x - z) < minDif)) then

minDif := abs(x - z);

end

else if (y >= z) and (y >= x) then begin

sum := sum + y;

if (((abs(y - x)) mod 109 <> 0) and (abs(y - x) < minDif)) then

minDif := abs(y - x);

if (((abs(y - z)) mod 109 <> 0) and (abs(y - z) < minDif)) then

minDif := abs(y - z);

end

else if (z >= x) and (z >= y) then begin

sum := sum + z;

if (((abs(z - y)) mod 109 <> 0) and (abs(z - y) < minDif)) then

minDif := abs(z - y);

if (((abs(z - x)) mod 109 <> 0) and (abs(z - x) < minDif)) then

minDif := abs(z - x);

end;

end;

if sum mod 109 <> 0 then

writeln(sum)

else writeln(sum - minDif);

end.

 

В ре­зуль­та­те ра­бо­ты дан­но­го ал­го­рит­ма при вводе дан­ных из файла A ответ  — 784594, из файла B  — 8819088760.

 

При­ме­ча­ние.

Путь к файлу не­об­хо­ди­мо ука­зать со­глас­но рас­по­ло­же­нию файла на Вашем ком­пью­те­ре.

 

При­ведём ре­ше­ние Дмит­рия Кры­ло­ва на языке Python:

f = open('27a.txt')

n = int(f.readline())

summ = 0

nekr109 = 10000000000000

for i in range(n):

a,b,c = f.readline().split()

a = int(a)

b = int(b)

c = int(c)

summ += max(a, b, c)

n1 = max(a, b, c) - min(a, b, c)

sr = a+b+c-max(a, b, c) - min(a, b, c)

n2 = max(a, b, c) - sr

if n1%109!=0:

nekr109 = min(nekr109, n1)

if n2%109!=0:

nekr109 = min(nekr109, n2)

if summ%109!=0:

print(summ)

else:

print(summ-nekr109)

 

При­ведём ре­ше­ние Юрия Кра­силь­ни­ко­ва на языке Python:

a = [sorted(map(int,s.split())) for s in open('27.txt')][1:]

s = sum(x[2] for x in a)

difs = [x[2]-x[0] for x in a if (x[2]-x[0])%109 !=0 ] + [x[2]-x[1] for x in a if (x[2]-x[1])%109 !=0 ]

print(s if s%109 != 0 else s-min(difs))

Источник: ЕГЭ по ин­фор­ма­ти­ке 05.04.2021. До­сроч­ная волна
Раздел кодификатора ФИПИ: