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

Дана по­сле­до­ва­тель­ность N целых по­ло­жи­тель­ных чисел. Не­об­хо­ди­мо опре­де­лить ко­ли­че­ство пар эле­мен­тов этой по­сле­до­ва­тель­но­сти, сумма ко­то­рых де­лит­ся на m  =  80 и при этом хотя бы один эле­мент из пары боль­ше b  =  50.

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

Файл A

Файл B

В пер­вой стро­ке вход­ных дан­ных задаётся ко­ли­че­ство чисел N (2 ≤ N ≤ 10 000). В каж­дой из по­сле­ду­ю­щих N строк за­пи­са­но одно на­ту­раль­ное число, не пре­вы­ша­ю­щее 10 000.

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

6

40

40

120

30

50

110

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

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

 

Ответ:

 

По­яс­не­ние. Из дан­ных шести чисел можно со­ста­вить три пары, удо­вле­тво­ря­ю­щие усло­вию: (40, 120), (40, 120), (50, 110). У пар (40, 40) и (30, 50) сумма де­лит­ся на 80, но оба эле­мен­та в этих парах не пре­вы­ша­ют 50.

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

Ре­ше­ние.

Сумма двух эле­мен­тов крат­на m, если сумма их остат­ков от де­ле­ния на m равна m или 0.

Со­зда­дим два мас­си­ва по m эле­мен­тов в каж­дом и будем хра­нить в них ко­ли­че­ство эле­мен­тов по­сле­до­ва­тель­но­сти, име­ю­щих со­от­вет­ству­ю­щий оста­ток от де­ле­ния на m; в мас­си­ве a0 будем под­счи­ты­вать эле­мен­ты, не пре­вы­ша­ю­щие b, в мас­си­ве a1  — пре­вы­ша­ю­щие.

После за­вер­ше­ния ввода ко­ли­че­ство под­хо­дя­щих пар с мень­шим остат­ком p от 1 до 39 можно под­счи­тать по фор­му­ле:

(a0[p] + a1[p])*a1[mp] + a1[p]*a0[mp].

Для остат­ков 0 и 40 оста­ток у чисел из пары сов­па­да­ет, по­это­му ко­ли­че­ство пар для этих остат­ков равно:

a0[p]*a1[p] + a1[p]*(a1[p]−1)/2.

Общее ко­ли­че­ство пар можно найти как сумму пар по всем остат­кам. Ниже при­ве­де­на про­грам­ма на ал­го­рит­ми­че­ском языке, ре­а­ли­зу­ю­щая этот ал­го­ритм.

 

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

const m = 80;

const b = 50;

var

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

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

i, N: integer;

x: integer;

p: integer;

s: integer;

f: text;

begin

for i := 0 to m-1 do begin

a0[i] := 0;

a1[i] := 0;

end;

assign(f,'28130_A.txt');

reset(f);

readln(f, N);

for i := 0 to N-1 do begin

readln(f, x);

p:= x mod m;

if x <= b then a0[p] := a0[p]+1

else a1[p] := a1[p]+1;

end;

p := 0;

s := a0[p]*a1[p] + ((a1[p]*(a1[p]-1)) div 2);

p := m div 2;

s := s + a0[p]*a1[p] + ((a1[p]*(a1[p]-1)) div 2);

for p := 1 to ((m div 2)-1) do

s := s + (a0[p]+a1[p])*a1[m-p] + a1[p]*a0[m-p];

writeln(s);

end.

 

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

 

При­ведём ре­ше­ние за­да­чи Да­ви­да Ша­му­гия на языке PascalABC.

const m = 80;

const b = 50;

var

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

i,j,n,x,c,t,p:integer;

f:text;

begin

c:=0;

for i:=0 to m-1 do

for j:=0 to 1 do

a[i,j]:=0;

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

reset(f);

readln(f,n);

readln(f,x);

for i:=1 to n-1 do begin

t:=0;

if x > b then t:=1;

inc(a[x mod m,t]);

readln(f,x);

p:=(m - x mod m) mod m;

if x > b then

c:=c+a[p,0]+a[p,1]

else

c:=c+a[p,1]

end;

print(c)

end.

 

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

 

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

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

 

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

f=open('28130_B.txt')

n=int(f.readline())

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

i=0

k=0

while i!=n:

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

if (numbers[i]+numbers[h])%80==0 and (numbers[i]>50 or numbers[h]>50):

k=k+1

i=i+1

print(k)

 

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

f = open('28130_A.txt')

n = int(f.readline())

a = [0]*51

b = [0]*80

for i in range (0,n):

x = int(f.readline())

if x <= 50:

a[x%80] += 1

else:

b[x%80]+=1

ans = ((b[40]*(b[40]-1))//2) +((b[0]*(b[0]-1))//2)

for i in range (1,len(a)):

ans += a[i]*b[80-i]

if i <= 39:

ans += b[i] * b[80 - i]

print(ans)

 

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

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

cnts = [[0]*2 for _ in range(80)]

k = 0

for x in a:

r = x%80

d = (80-r)%80

k += sum(cnts[d]) if x > 50 else cnts[d][0]

cnts[r][0 if x > 50 else 1] += 1

print(k)

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