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

На вход про­грам­мы по­сту­па­ет по­сле­до­ва­тель­ность из n целых по­ло­жи­тель­ных чисел. Рас­смат­ри­ва­ют­ся все пары эле­мен­тов по­сле­до­ва­тель­но­сти ai и aj, такие, что i < j и ai > aj (пер­вый эле­мент пары боль­ше вто­ро­го; i и j  — по­ряд­ко­вые но­ме­ра чисел в по­сле­до­ва­тель­но­сти вход­ных дан­ных). Среди пар, удо­вле­тво­ря­ю­щих этому усло­вию, не­об­хо­ди­мо найти и на­пе­ча­тать пару с мак­си­маль­ной сум­мой эле­мен­тов, ко­то­рая де­лит­ся на m  =  120. Если среди най­ден­ных пар мак­си­маль­ную сумму имеют не­сколь­ко, то можно на­пе­ча­тать любую из них.

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

Файл A

Файл B

В пер­вой стро­ке вход­ных дан­ных задаётся ко­ли­че­ство чисел n (2 ≤ n ≤ 12 000).

В каж­дой из по­сле­ду­ю­щих n строк за­пи­са­но одно целое по­ло­жи­тель­ное число, не пре­вы­ша­ю­щее 10 000.

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

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

6

60

140

61

100

300

59

При­мер вы­ход­ных дан­ных для при­ведённого выше при­ме­ра вход­ных дан­ных:

140 100 В от­ве­те ука­жи­те че­ты­ре числа: сна­ча­ла ис­ко­мую пару чисел для файла А (два числа через про­бел), затем для файла B (два числа через про­бел).

 

Ответ:

 

По­яс­не­ние. Из шести за­дан­ных чисел можно со­ста­вить три пары, сумма эле­мен­тов ко­то­рых де­лит­ся на m  =  120: 60 + 300, 140 + 100 и 61 + 59. Во вто­рой и тре­тьей из этих пар пер­вый эле­мент боль­ше вто­ро­го, но во вто­рой паре сумма боль­ше.

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

Ре­ше­ние.

Сумма ai и aj де­лит­ся на m, если сумма остат­ков этих чисел от де­ле­ния на m равна 0 или m. Для каж­до­го из остат­ков от де­ле­ния на m среди уже про­смот­рен­ных эле­мен­тов будем хра­нить мак­си­маль­ное число, име­ю­щее со­от­вет­ству­ю­щий оста­ток от де­ле­ния на m. Для этого будем ис­поль­зо­вать мас­сив r дли­ной m, из­на­чаль­но с эле­мен­та­ми, рав­ны­ми 0. Все счи­тан­ные зна­че­ния при этом можно не хра­нить.

Оче­ред­ное счи­тан­ное число a будем рас­смат­ри­вать как воз­мож­ный пра­вый эле­мент ис­ко­мой пары. Пусть оста­ток от де­ле­ния a на m равен p. Тогда если r[mp] > 0, то сумма a и r[mp] де­лит­ся на m, и при усло­вии r[mp] > a эта пара  — кан­ди­дат для от­ве­та. Если их сумма боль­ше преды­ду­ще­го от­ве­та, то за­ме­ним его. При этом если оста­ток от де­ле­ния a на m равен 0, то рас­смат­ри­вать надо пару a и r[0].

По окон­ча­нии об­ра­бот­ки эле­мен­та a не­об­хо­ди­мо об­но­вить эле­мент r[p] зна­че­ни­ем a, если a > r[p].

 

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

const m = 120; {ко­ли­че­ство раз­лич­ных остат­ков}

var

{хра­не­ние мак­си­маль­но­го зна­че­ния для каж­до­го из остат­ков}

r: array[0..m-1] of integer;

n, a, i, p, left, right: integer;

f: text;

begin

assign(f,'28131_B.txt');

reset(f);

readln(f, n);

{об­ну­ле­ние мас­си­ва r}

for i := 0 to m - 1 do

r[i] := 0;

{об­ну­ле­ние пе­ре­мен­ных для за­пи­си от­ве­та}

left := 0; right := 0;

{ввод зна­че­ний, поиск ис­ко­мой пары}

for i := 1 to n do

begin

readln(f,a); {счи­ты­ва­ем оче­ред­ное зна­че­ние}

p := a mod m;

if p = 0 then

begin

if (r[0] > a) and (r[0] + a > left + right) then

begin

left := r[0]; right := a {об­нов­ле­ние от­ве­та}

end

end

else

begin

if (r[m - p] > a) and (r[m - p] + a > left + right) then

begin

left := r[m - p]; right := a {об­нов­ле­ние от­ве­та}

end

end;

{об­нов­ле­ние эле­мен­та r для со­от­вет­ству­ю­ще­го остат­ка}

if a > r[p] then r[p] := a

end;

writeln(left, ' ',right)

end.

 

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

 

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

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

 

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

def f(x,dict):

for key,keybord in dict.items():

if key==x:

return keybord

g=open('28131_B.txt')

n=int(g.readline())

numbers=[int(x) for x in g]

i=0

dict={}

k=0

maxk=0

while i!=n:

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

if ((numbers[h]+numbers[i]) % 120 ==0) and (numbers[h] < numbers[i]) and (numbers.index(numbers[h]) > numbers.index(numbers[i])):

dict[numbers[h]+numbers[i]]=numbers[i],numbers[h]

k=numbers[h]+numbers[i]

maxk=max(k,maxk)

i=i+1

if maxk==0:

print('00')

else:print('мак­си­маль­ная сумма:',maxk,'.Ис­ко­мые эле­мен­ты:',f(maxk,dict))

 

При­ведём ре­ше­ние Га­ли­ны Не­спя­ти­ной на языке Python.

f = open('28131_B.txt')

s = [int(i) for i in f]

r = s[0]

m=0

i1=0

j1=0

for i in range(1,r-1):

for j in range(i+1,r):

if s[i]>s[j] and (s[i]+s[j])%120==0 and (s[i]+s[j])>=m:

m=s[i]+s[j]

i1=i

j1=j

print(m,s[i1],s[j1]

 

При­ведём ре­ше­ние Софьи Лит­ви­ной на языке Python.

f = open('28131_B.txt').read().split('\n')[1:]

f = list(map(int, f))

maxs = 0

maxs_l = []

for i in range(len(f)):

ostf = f[i] % 120

f1 = [j for j in f[1:] if j < f[i] and (j%120 + ostf) % 120 == 0]

if len(f1):

s = f[i] + max(f1)

if s > maxs:

maxs_l.append([f[i], max(f1), s])

maxs = s

print(*max(maxs_l, key=lambda e: e[2]))

 

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

d = {}

params = (0,0)

a = [int(s) for s in open('28131_B.txt')][1:]

for x in a:

res = x%120

dop = 0 if res == 0 else 120 - res

if dop in d and d[dop] > x and d[dop] + x > sum(params):

params = (d[dop],x)

d[res] = max(d.get(res,0),x)

print(*params)


Аналоги к заданию № 28131: 28133 Все

Раздел кодификатора ФИПИ: