{ задание 1} const n=17; var a:array[1..n] of integer; i,k:integer; begin Randomize; k:=0; for i:=1 to n do begin a[i]:=Random(99)+1; Write(a[i],' '); if a[i] mod 2=0 then k:=k+1 end; Writeln; Writeln('k=',k) end.
{ задание 2/3} const n=17; var a:array[1..n] of integer; i,s:integer; begin Randomize; s:=0; for i:=1 to n do begin a[i]:=Random(99)+1; Write(a[i],' '); if a[i] mod 10=2 then s:=s+a[i] end; Writeln; Writeln('s=',s) end.
ответ:Алгоритм Карацубы — метод быстрого умножения со сложностью вычисления nlog23. В то время, как наивный алгоритм, умножение в столбик, требует n2 операций. Следует заметить, что при длине чисел короче нескольких десятков знаков (точнее определяется экспериментально), быстрее работает обычное умножение.
Представим, что есть два числа A и B длиной n в какой-то системе счисления BASE:
A = an-1an-2...a0
B = bn-1an-2...a0, где a?, b? — значение в соотв. разряде числа.
Каждое из них можно представить в виде суммы их двух частей, половинок длиной m = n / 2 (если n нечетное, то одна часть короче другой на один разряд:
Здесь нужно 4 операции умножения (части формулы * BASE? * m не являются умножением, фактически указывая место записи результата, разряд). Но с другой стороны:
Посмотрев на выделенные части в обоих формулах. После несложных преобразований количество операций умножения можно свести к 3-м, заменив два умножения на одно и несколько операций сложения и вычитания, время выполнения которых на порядок меньше:
const
n=17;
var
a:array[1..n] of integer;
i,k:integer;
begin
Randomize;
k:=0;
for i:=1 to n do begin
a[i]:=Random(99)+1;
Write(a[i],' ');
if a[i] mod 2=0 then k:=k+1
end;
Writeln;
Writeln('k=',k)
end.
Пример
43 86 43 13 24 18 93 38 38 59 15 75 12 92 8 72 8
k=10
{ задание 2/3}
const
n=17;
var
a:array[1..n] of integer;
i,s:integer;
begin
Randomize;
s:=0;
for i:=1 to n do begin
a[i]:=Random(99)+1;
Write(a[i],' ');
if a[i] mod 10=2 then s:=s+a[i]
end;
Writeln;
Writeln('s=',s)
end.
Пример
58 39 12 24 91 57 14 44 47 61 31 10 95 54 42 98 76
s=54
ответ:Алгоритм Карацубы — метод быстрого умножения со сложностью вычисления nlog23. В то время, как наивный алгоритм, умножение в столбик, требует n2 операций. Следует заметить, что при длине чисел короче нескольких десятков знаков (точнее определяется экспериментально), быстрее работает обычное умножение.
Представим, что есть два числа A и B длиной n в какой-то системе счисления BASE:
A = an-1an-2...a0
B = bn-1an-2...a0, где a?, b? — значение в соотв. разряде числа.
Каждое из них можно представить в виде суммы их двух частей, половинок длиной m = n / 2 (если n нечетное, то одна часть короче другой на один разряд:
A0 = am-1am-2...a0
A1 = an-1an-2...am
A = A0 + A1 * BASEm
B0 = bm-1bm-2...b0
B1 = bn-1bn-2...bm
B = B0 + B1 * BASEm
Тогда: A * B = ( A0 + A1 * BASEm ) * ( B0 + B1 * BASEm ) = A0 * B0 + A0 * B1 * BASEm + A1 * B0 * BASEm + A1 * B1 * BASE2 * m = A0 * B0 + ( A0 * B1 + A1 * B0 ) * BASEm + A1 * B1 * BASE2 * m
Здесь нужно 4 операции умножения (части формулы * BASE? * m не являются умножением, фактически указывая место записи результата, разряд). Но с другой стороны:
( A0 + A1 ) * ( B0 + B1 ) = A0 * B0 + A0 * B1 + A1 * B0 + A1 * B1
Посмотрев на выделенные части в обоих формулах. После несложных преобразований количество операций умножения можно свести к 3-м, заменив два умножения на одно и несколько операций сложения и вычитания, время выполнения которых на порядок меньше:
A0 * B1 + A1 * B0 = ( A0 + A1 ) * ( B0 + B1 ) — A0 * B0 — A1 * B1
Окончательный вид выражения:
A * B = A0 * B0 + (( A0 + A1 ) * ( B0 + B1 ) — A0 * B0 — A1 * B1 ) * BASEm + A1 * B1 * BASE2 * m
Объяснение: