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

Дана по­сле­до­ва­тель­ность из N на­ту­раль­ных чисел. Рас­смат­ри­ва­ют­ся все её не­пре­рыв­ные под­по­сле­до­ва­тель­но­сти, такие что сумма эле­мен­тов каж­дой из них крат­на k  =  43. Най­ди­те среди них под­по­сле­до­ва­тель­ность с мак­си­маль­ной сум­мой, опре­де­ли­те её длину. Если таких под­по­сле­до­ва­тель­но­стей най­де­но не­сколь­ко, в от­ве­те ука­жи­те ко­ли­че­ство эле­мен­тов самой ко­рот­кой из них.

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

Файл A

Файл B

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

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

14

1

2

1

4

93

8

5

95

6

4

3

2

8

6 В от­ве­те ука­жи­те два числа: сна­ча­ла зна­че­ние ис­ко­мой длины для файла А, затем  — для файла B. Для при­ве­ден­но­го при­ме­ра ответ  — 7.

 

Пре­ду­пре­жде­ние: для об­ра­бот­ки файла B не сле­ду­ет ис­поль­зо­вать пе­ре­бор­ный ал­го­ритм, вы­чис­ля­ю­щий сумму для всех воз­мож­ных ва­ри­ан­тов, по­сколь­ку на­пи­сан­ная по та­ко­му ал­го­рит­му про­грам­ма будет вы­пол­нять­ся слиш­ком долго.

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

Ре­ше­ние.

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

f = open("27_B.txt")

n = int(f.readline())

mins = [1000000001 for i in range(43)]

minl = [0 for i in range(43)]

sum = 0

maxsum = 0

minlen = 0

ms = 0

l = 0

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

num = int(f.readline())

sum = sum + num

d = sum % 43

if d == 0:

maxsum = sum

minlen = i

else:

ms = sum - mins[d]

l = i - minl[d]

if ms > maxsum:

maxsum = ms

minlen = l

if (ms == maxsum) and (l < minlen):

maxsum = ms

minlen = l

if sum < mins[d]:

mins[d] = sum

minl[d] = i

print(minlen)

 

Ответ: 185  329329.

 

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

f = open('27_B.txt')

n = int(f.readline())

pr = [0]

a = [[1e9, -1] for i in range(43)]

a[0][0] = -1

for i in range(n):

x = int(f.readline())

pr.append(pr[i] + x)

a[pr[i+1]%43] = [min(i, a[pr[i+1]%43][0]), max(i, a[pr[i+1]%43][1])]

mx = ln = 0

for i in range(43):

if a[i][0] != 1e9 and a[i][1] != -1 and a[i][1] != a[i][0]:

s = pr[a[i][1]+1] - pr[a[i][0]+1]

if s > mx:

mx = s

ln = a[i][1] - a[i][0]

if s == mx and a[i][1] - a[i][0] < ln:

ln = a[i][1] - a[i][0]

print(ln)

 

 

 

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

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

p = 0

b = [0]

nk = [[0]] + [[] for _ in range(42)]

for i in range(len(a)):

p += a[i]

b.append(p)

r = p%43

if len(nk[r]) < 2: nk[r].append(i+1)

else: nk[r][1] = i+1

r = sorted([(b[x[1]]-b[x[0]],x[0]-x[1]) for x in nk if len(x) == 2],reverse=True)

print(-r[0][1])

 

При­ве­дем дру­гое ре­ше­ние.

Будем по­сле­до­ва­тель­но счи­ты­вать числа из файла, сум­ми­руя все по­лу­чен­ные числа. В мас­си­ве mins будем на­кап­ли­вать суммы с остат­ка­ми от 0 до 42, в мас­си­ве minl будем на­кап­ли­вать длины для этих сумм. Каж­дую ите­ра­цию цикла будем про­ве­рять, де­лит­ся ли те­ку­щая сумма на 43 без остат­ка. Если те­ку­щая сумма де­лит­ся на 43 с опре­делённым остат­ком, будем вы­чи­тать из неё сумму с таким же остат­ком из мас­си­ва mins и за­пи­сы­вать по­лу­чен­ное зна­че­ние в пе­ре­мен­ную maxsum (если по­лу­чен­ная сумма будет боль­ше те­ку­ще­го зна­че­ния пе­ре­мен­ной), то же самое будем про­де­лы­вать для ми­ни­маль­ной длины по­сле­до­ва­тель­но­сти.

 

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

var

i, d: longint;

n: longint;

mins: array [1..42] of longint;

minl: array [1..42] of longint;

sum, maxsum, minlen, num, ms, l: longint;

f: text;

begin

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

reset(f);

readln(f, n);

for i := 1 to 42 do mins[i] := 1000000001;

for i := 1 to 42 do minl[i] := 0;

sum := 0;

maxsum := 0;

minlen := 0;

ms := 0;

l := 0;

for i := 1 to n do begin

readln(f, num);

sum := sum + num;

d := sum mod 43;

if d = 0 then begin

maxsum := sum;

minlen := i;

end

else begin

ms := sum - mins[d];

l := i - minl[d];

if ms > maxsum then begin

maxsum := ms;

minlen := l;

end;

if (ms = maxsum) and (l < minlen) then begin

maxsum := ms;

minlen := l;

end;

if sum < mins[d] then begin

mins[d] := sum;

minl[d] := i;

end;

end;

end;

writeln(minlen);

end.

 

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

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