Решение задачи 1.
Если вспомнить, что признаком деления на 9 в десятичной системе счисления является делимость на 9 суммы цифр числа действительно, пусть есть число
S = a[n]*10n + a[n-1]*10(n-1) + ... + a[1]*10 + a[0].
S mod 9 = (a[n]*(10n-1)+a[n] + a[n-1]*(10(n-1)-1)+a[n-1] + ... + a[1]*(10-1)+a[1] + a[0]) mod 9
А так как 10k - 1 делится на 9 нацело, то и
S mod 9 = (a[n] + ... +a[1] +a[0]) mod 9,
и т.д.), то аналогично получаем, что признаком деления на 15 в системе счисления с базисом 16 будет делимость на 15 суммы всех шестнадцатеричных цифр числа.
Мы разбиваем двоичное число справа налево на тетрады, которые однозначно можно преобразовать в шестнадцатеричные цифры, находим их сумму и делим ее на 15. Если остаток 0, то введенное число делится на 15, иначе - нет.
[Назад]
Решение задачи 2.
Разумеется, можно непосредственно вычислить это число в десятичной системе счисления, после чего разделить его на m, но в этом случае придется представлять число в виде (например) массива цифр и моделировать операции над этим числом. Существует другой простой алгоритм.
В системе счисления с основанием K число представляется в виде
a[n]*Kn + a[n-1]*K(n-1) + ... +a[0]*K0.
Найдем остаток от деления его на m (остаток от деления a на b обозначим a mod b):
(a[n]*Kn + a[n-1]*K(n-1) + ... +a[0]*K0) mod m =
mod m = =
Это следует из следующих соображений:
пусть Ki mod m=t, тогда Ki =p*m+t, и
(a[i]*Ki) mod m = (a[i] * (p*m+t)) mod m =
= (a[i]* p*m) mod m + (a[i]*t) mod m =
= (a[i] * (Ki mod m)) mod m,
при этом для любых чисел b[i] выполняется
Отметим также очевидное равенство
Ki mod m =[(K(i-1) mod m) * K] mod m,
т.к. если K(i-1) = p*m+t, то K(i-1) mod m = t,
Ki = p*m*K+t*K и Ki mod m = t*K mod m =
= [(K(i-1) mod m)*K] mod m.
Запись этого алгоритма (тут a[i] - K-ичные цифры числа):
s:=0; t:=1;
for i:=0 to n do
begin
s:=(s+a[i]*t) mod m;
t:=t*K mod m;
end;
В переменной S после окончания работы алгоритма будет храниться искомый остаток.
[Назад]
Решение задачи 3.
Задача решается также, как и предыдущая:
N mod K =
где (s+1)! mod K =
Алгоритм запишется следующим образом:
остаток:=0;
faktorial:=1;
for i:=1 to s+1 do
begin
остаток:=(остаток+(d[i-1] mod k)*faktorial) mod k; faktorial:=(faktorial * ((i+1) mod k)) mod k;
end;
В переменной остаток после выхода из цикла будет искомое значение.
[Назад]
Решение задачи 4.
Воспользуйтесь тем, что
U[1] + U[1] = U[2], (1)
U[i] + U[i] = U[i] + U[i-1] + U[i-2] = U[1+1] + U[i-2], (2)
U[i] + U[i-1] = U[i+1]. (3)
Суммируем числа A и B поразрядно, используя приведенные выше правила, начиная со старших разрядов. После применения любого из правил опять начинаем просмотр числа со старших разрядов.
Проведем суммирование чисел '10101' и '100' из задачи.
10101
+ 100
10 Первые два разряда просто сносятся,
+ 1001 затем применяем правило (2),
+ 01 и добавляем последние два разряда
+ 00 чисел A и B
11001 Для двух первых разрядов применяем правило (3)
+ 01
+ 00
100001
+ 01 Правило (1)
+ 00
100010
[Назад]
Решение задачи 5.
Алгоритм следующий:
cnt:=0; cnt - счетчик единиц в i.
while (i<>0) do цикл повторяется число раз, равное
begin числу единиц в i. " Убираем " крайнюю
i:=(i-1) and i; справа единицу в двоичной записи
cnt:=cnt+1; числа.
end;
Пример:
110 = i
101 = i-1
100 = i and (i-1)
[Назад]
Решение задачи 6.
Пусть a(k) - k-ый член последовательности.
Рассмотрим последовательность, формируемую по следующему правилу:
a(0)=0;
ряд
a(0)...a(2k-1)
получаем приписыванием к этой последовательности справа этой же последовательности, но при этом каждый член приписываемой части увеличивается на единицу. Получаем
0->01->0112->01121223->...
Докажем, что a(k) есть сумма единиц в двоичном представлении числа k.
Доказательство проведем по индукции. Для a(0)=0 это справедливо. Пусть предположение справедливо для всех a(i),
0<=i<=2(k-1)-1 (т.е. для всех чисел i, состоящих из не более чем k-1-го двоичных разрядов). Тогда в двоичном разложении числа l, 2(k-1)<=l<2k, в k-ом разряде появляется добавочная единица, и поэтому
a(l)=1+a(l-2(k-1))),
ч.т.д.
Возьмем a(i) mod 3, и получим число, стоящее на i-ом месте в последовательности, описанной в условии задачи.
Для того, чтобы найти a(i), необходимо, по доказанному, сосчитать количество единиц в двоичной записи числа i - см. задачу 5.
[Назад]
Решение задачи 7.
Будем менять местами содержимое переменных A и B. Существует несколько способов сделать это.
1.
Оператор |
Значение в A |
Значение в B |
A:=A+B |
A+B |
B |
B:=A-B |
A+B |
A |
A:=A-B |
B |
A |
2. Можно использовать логическую операцию XOR (исключающее или). Таблица истинности для XOR следующая:
1 XOR 1 = 0 |
1 XOR 0 = 1 |
0 XOR 0 = 0 |
0 XOR 1 = 1 |
Операция XOR над двумя переменными в машине реализуется как побитовая операция над двоичным представлением чисел. Поэтому, в частности, A XOR A = 0, A XOR B = B XOR A, A XOR 0 = A.
Оператор |
Значение в A |
Значение в B |
A:=A XOR B |
A XOR B |
B |
B:=A XOR B |
A XOR B |
(A XOR ) XOR B=A XOR(B XOR B)=A XOR 0 = A |
A:=A XOR B |
(A XOR B) XOR A=B XOR (A XOR A)=B |
A |
[Назад]
Решение задачи 8.
Если рассмотреть битовые представления числа A[i,j], помечающего точку (i,j) и чисел i и j, то обнаруживается, что A[i,j]=i XOR j, откуда получается, что A[i,j] XOR i=j,
A[i,j] XOR j=i.
Покажем, что A[i,j]=i XOR j.
1. Число A[i,j]=i XOR j не встречалось еще ни в строке i, ни в столбце j. От противного: существует такое j', что i XOR j = i XOR j' => i XOR j XOR i = i XOR j' XOR i => j'=j;
2. Пусть существует такое k<i XOR j, что k=i XOR L = j XOR M, и k еще не встречалось в строке i и столбце j (напомним, что по предположению все остальные уже заполненные элементы равны i XOR j, поэтому L>j и M>i).
Тогда, так как M>i, то существует бит с номером t такой, что для любого R>t биты Mr и ir равны, t-ый бит Mt=1, it=0. Но так как j XOR M < j XOR i, то Jt=1.
Так как L>j и L XOR i=j XOR M, то L = j XOR M XOR i. Рассмотрим i XOR M. В силу вышесказанного для любого бита с номером R, R>t, (i XOR M)r=0, а (i XOR M)t=1.
При этом Jt=1, следовательно
(i XOR j XOR M)r = Jr для r>t и
(i XOR j XOR M)t = 0 для r=t,
то есть L<j ?! Противоречие.
[Назад]
Решение задачи 10.
Так как q<p, то цифры a и b должны лежать в пределах от 0 до q-1.
Распишем A в системе с основанием p:
A= ... = (ap+b)(p-2) + p-4 + ...) = { находим сумму бесконечно убывающей геометрической прогрессии со знаменателем p-2} =
=
Аналогично для A в системе с основанием q выполняется
A=
Получаем
(bq+a)(p2-1)=(ap+b)(q2-1)
a[p(q2-1)-(p2-1)]=b[q(p2-1)-(q2-1)].
Вычисляем выражения в квадратных скобках; обозначим их соответственно u и v: au=bv.
Находим НОД(u,v)=s; обозначим r=u/s, f=v/s.
Получаем
ar=bf,
r и f взаимно просты, следовательно, решениями этого равенства
будут числа
a=fk, b=rk, k=1,2, ... ,
при этом мы берем только те a и b, для которых одновременно выполняется
а) a<>b
b) a<r
c) b<r
Нахождение НОД - см. задачу 12.
[Назад]
Решение задачи 11.
Очевидное решение: При попытке непосредственно вычислять координаты концов сегментов, принадлежащих множеству K[n], и определить, принадлежит ли a/b одному из этих сегментов даже для не слишком больших n за счет потери точности при вычислениях и из-за ограниченного числа знаков в машинном представлении чисел с плавающей точкой данный подход дает неверный ответ для большинства входных данных. При больших n вообще будет наблюдаться потеря значимости: число при делении на 3 станет таким малым, что в машине оно будет представляться нулем.
Рассмотрим другой метод решения этой задачи. Так как мы постоянно должны делить сегменты на три части, то это наталкивает на мысль использовать троичную систему счисления и троичные дроби. В первой из удаленных интервалов (1/3,2/3) попадают только те точки
x=0.a[1] a[2] a[3] ...
в троичном разложении которых a[1]=1, кроме точки 1/3=0.1000... -правого конца сегмента [0,1/3]. Таким образом, в K [1] остаются все те точки, у которых a[1] <>1, либо a[1]=1, a[2] = a[3] = ...= = 0. Аналогично, в множестве K[i], i>=0, содержатся точки, у которых ни одно из чисел a[j], 1<=j<=i, не равно 1, а также точки, удовлетворяющие условию: a[j]=1, j - фиксировано, 1<=j<=i, a[l]<>1, l<j, и a[l] =0 для любого l>j (то есть, в записи троичной дроби только одна позиция равна 1, после нее все остальные позиции нулевые. Эти дроби соответствуют правым концам сегментов из множества K[i]).
Запись алгоритма на Паскале имеет вид:
x:=a; i:=1;
while (i<=n) or (x<>1) or (a<>0) do
begin
a:=a*3 mod b;
x:=a*3 div b;
i:=i+1;
end;
if (x=1) and (a<>0) and (n<>0)
then writeln(' Не принадлежит') else writeln(' Принадлежит');
[Назад]
Решение задачи 12.
Нас интересуют точки решетки (с целыми координата-
* ми) в первом квадранте, попадающие внутрь круга
* * * радиуса (n в степени 1/2). Интересующее нас
* * * * множество (назовем его X) состоит из объедине-
* * * * ния вертикальных столбцов убывающей высоты.
* * * * * Идея решения состоит в том, чтобы "двигаться
вдоль его границы", спускаясь по верхнему его краю, как по
лестнице. Координаты движущейся точки обозначим . Введем
еще одну переменную s и будем поддерживать истинность такого ус-
ловия:
находится сразу над k-ым столбцом;
s - число точек в предыдущих столбцах.
Формально:
l - минимальное среди тех l >= 0, для которых не принад-
лежит X;
s - число пар натуральных x, y, для которых x < k и при-
надлежит X.
Обозначим эти условия через (И).
k := 0; l := 0;
while "<0,l> принадлежит X" do begin
| l := l + 1;
end;
{k = 0, l - минимальное среди тех l >= 0,
для которых <k,l> не принадлежит X }
s := 0;
{инвариант: И}
while not (l = 0) do begin
| s := s + l;
| {s - число точек в столбцах до k-го включительно}
| k := k + 1;
| {точка <k,l> лежит вне X, но, возможно, ее надо сдвинуть
| вниз, чтобы восстановить И }
| while (l <> 0) and ("<k, l-1> не принадлежит X") do begin
| | l := l - 1;
| end;
end;
{И, l = 0, поэтому k-ый столбец и все следующие пусты, а
s равно искомому числу}
Оценка числа действий очевидна: сначала мы движемся вверх не более чем на (n в степени 1/2) шагов, а затем вниз и вправо - в каждую сторону не более чем на (n в степени 1/2) шагов.
[Назад]
Решение задачи 13.
Число вида 2p-1 * (2p - 1), в двоичном представлении имеет р единиц и р-1 нулей. Максимальное значение р определяется как
[(log2N)/2]+1.
Затем проверяется является ли число совершенным для полученного значения p. Оно является совершенным, если для простого значения p, число 2p -1 является простым. Если получили несовершенное число, уменьшаем p на 1 и снова проверяем, является ли данное число простым.
Совершенные числа получаются для значений р равных 2,3,5,7,13,17,19,31,61,89,107,127.
[Назад]
Решение задачи 14.
Запишем уравнение в виде
sXeAk + pY = nYmAt + rX.
Приравнивая коэффициенты при X,A и Y, получаем:
X se=k
A p=nm (*)
Y sk=nt
Так как коэффициенты в формуле должны быть взаимно простыми, то следует найти НОД чисел k и t (Задача 12). Пусть (k,t)=d. Тогда s*(k/d)=n*(t/d), и числа k/d и t/d являются взаимно простыми, следовательно, n=k/d, а s=t/d.
По (*) находим остальные коэффициенты.
[Назад]
Решение задачи 15.
По заданным координатам трех вершин мы можем найти площадь треугольника ABC
Sabc=(bx-ay)/2
Если a=0, то минимальная площадь Smin=b/2, если b=0, то Smin=a/2. Если же обе координаты отличны от нуля, то из алгоритма Евклида для нахождения НОД(a,b)=(a,b), следует существование таких целых x и y, что ABS(bx-ay)=(a,b), и именно эти x и y минимизируют площадь треугольника ABC.
Нахождение НОД - задача 12.
[Назад]
Решение задачи 16.
Обозначим S=НОД(V1,...,Vn). Если V делится нацело на S, то в сосуд с помощью банок можно налить V литров воды, иначе - нет.
[Назад]
Решение задачи 17.
k := n; a := 1; b := 0;
{инвариант: 0 <= k, f (n) = a * f(k) + b * f (k+1)}
while k <> 0 do begin
| if k mod 2 = 0 then begin
| | l := k div 2;
| | {k = 2l, f(k) = f(l), f (k+1) = f (2l+1) = f(l) + f(l+1),
| | f (n) = a*f(k) + b*f(k+1) = (a+b)*f(l) + b*f(l+1)}
| | a := a + b; k := l;
| end else begin
| | l := k div 2;
| | {k = 2l + 1, f(k) = f(l) + f(l+1),
| | f(k+1) = f(2l+2) = f(l+1),
| | f(n) = a*f(k) + b*f(k+1) = a*f(l) + (a+b)*f(l+1)}
| | b := a + b; k := l;
| end;
end;
{k = 0, f(n) = a * f(0) + b * f(1) = b, что и требовалось}
[Назад]
Решение задачи 18.
В переменной стандартного типа такое большое число не поместится. Будем моделировать возведение 2 в степень n вычисляя последовательно 21, 22, ... , 2n, используя массив. В каждой ячейке массива будем хранить по (например) 4 десятичных цифры числа (т.е. в элементе A[1] - 4 последних цифры числа (разряды 0 -3), в A[2] - 4 предпоследних (разряды 4 - 7) и т.д.).
Оценим количество десятичных цифр в числе 2n, n<=1000. Это 10 000 * log10(2) + 1 < 15 000 цифр. Количество элементов массива возьмем равным 15000/4=3750. Введем переменную Nach, в которой будем хранить индекс элемента массива A, в котором находятся старшие значащие разряды вычисляемого сейчас числа.
var A: array[1 .. 3750] of word;
Nach: word;
I,N,j: word;
begin
for i:=2 to 3750 do A[i]:=0;
A[1]:=1; { сначала число в массиве A - это 20=1 }
read(N); { читаем степень }
Nach:=2; { индекс первой еще не использованной ячейки }
{ в массиве A }
for i:=1 to N do
begin
Perenos:=0; { перенос в следующий элемент массива A }
for j:=1 to Nach+1 do
begin
A[i]:=A[i]+A[i]+Perenos;
{ складываем 4 текущих разряда друг с другом, }
{ добавляя перенос из предыдущих 4-х разрядов }
if A[i]>=10000 { если в числе > 4 цифр }
then begin
Perenos:=A[i] div 10000; {то формируем перенос}
{ в старшие разряды }
A[i]:=A[i] mod 10000; { и оставляем в числе }
{ 4 последних цифры }
end
else Perenos:=0 { иначе переноса нет }
end; { к вложенному циклу for j }
if A[Nach+1]>0 { если был перенос в еще не }
then Nach:=Nach+1; { использованную ячейку }
{ массива A, то увеличиваем Nach }
end; { для цикла for i }
{ распечатка }
{ старшая тетрада печатается без ведущих нулей }
j:=1000; { ищем первую значащую цифру }
while (A[Nach] div j)=0 do j:=j div 10;
while j<>0 do begin
write(A[Nach] div j); { печать цифры }
A[Nach]:=A[Nach] mod j; { отбрасываем }
j:=j div 10; { напечатанную цифру }
end;
for i:=Nach-1 downto 1 do
begin
j:=1000;
for j:=1 to 4 do { 4 разряда }
begin
write(A[i] div j); { печатаем цифру }
A[i]:=A[i] mod j; { и отбрасывает ее }
j:=j div 10;
end
end
end. { программы }
[Назад]
Решение задачи 19.
Решается, аналогично задаче 18, моделированием вычисления
N1, N2, ... , NN.
[Назад]
Решение задачи 21.
Мы можем представить N! в виде произведения простых сомножителей:
N!=2A2*3A3*5A5*7A7*...,
где Ap - показатель степени, с которой простое число р входит в разложение. Видно, что нулей в конце числа столько же, сколько нулей в конце произведения 2A2*5A5, но так как, очевидно, что A2>A5, то количество нулей равно A5.
Для того, чтобы найти A5, необходимо вычислить сумму
+... ,
где - целая часть числа,
т.к. каждое пятое число в произведении N! делится на 5, каждое двадцать пятое число еще раз делится на 5, каждое 53 число, еще раз делится на 5, и т.д. То есть в (*) мы находим, сколько чисел в произведении N! делится на 5. Фрагмент программы выглядит следующим образом :
k:=5;
s:=0;
repeat
s:=s+N div k;
k:=k*5;
until (k>N);
После работы цикла в переменной S будет находиться A5.
[Назад]
Решение задачи 22.
Найдем простые множители числа P. Пусть это будут p1,..., pK. Для каждого множителя pI найдем число sI - степень, с ко торой pI входит в разложение P на простые сомножители. Как и в задаче 21 найдем максимальные числа m1, ..., mK, такие что N! делится на pI в степени mI, но не делится на pI в степени mI+1.
Получаем для нахождения m следующее уравнение:
,
где R=N!/[(p1m1)*(p2m2)*...*(pkmk)].
Минимальное из чисел mi div si и даст искомую степень M.
Рассмотрим пример:
N=15, P=135.
P=3*3*3*5, p1=3, s1=3, m1=15 div 3 + 15 div (3*3)=6
P2=5, s2=1, m2=3.
Получаем, что M=min{6 div 3, 3 div 1}=2.
Объясните, почему мы не можем применить формулу
M=N div P + N div P2 + N div P3 + ... ?
Приведем полностью программу, реализующую этот алгоритм.
{ Условие задачи.
На входе программе даются два числа N и P. Программа на выходе должна дать такое максимальное число M, что N! делится на P в степени M, но не делится на P в степени M+1.
Примечание.
1. Числа N и P так велики, что нет смысла считать значение N!.
2. Числа N и P являются натуральными.
}
uses crt;
const
max_long = 2147483647;
var
n,p,i,stp,m,mn,km : longint;
flag : boolean;
ch : char;
{ Функция howmany считает, сколько раз в разложении числа n!
присутствует множитель mn.
}
function howmany(mn,n:longint):longint;
var
pr1,pr2,pr3 : longint;
begin
pr1:=mn; pr2:=0; pr3:=1;
while pr3<>0 do
begin
pr3:=trunc(n/pr1);
pr1:=pr1*mn;
pr2:=pr2+pr3
end;
howmany:=pr2
end;
{ Функция st находит степень множителя mn в разложении
числа p на простые множители }
function st(mn:longint; var n:longint):longint;
var
prom: longint;
begin
prom:=0;
while (n mod mn)=0 do
begin
inc(prom);
n:=n div mn
end;
st:=prom
end;
begin
clrscr;
while true do
begin
write('Введите число N и P => '); read(n,p); { ввод }
if p<>1 then { если p=1 то число m }
begin { не существует }
m:=max_long;
i:=2;
flag:=true;
repeat
stp:=st(i,p);
{ stp после присваивания будет равно числу }
if (stp<>0) then
{ вхождений множителя i в разложении числа p }
begin
{ на простые множители. Если stp<>0,
то km будет равно числу вхождений множителя i }
km:=howmany(i,n);
{ в разложении числа n! на простые множители }
if (trunc(km/stp)<m) then
{ если km/stp меньше минимального отношения,
то сохраняем это значение.}
Begin
m:=trunc(km/stp);
if m=0 then flag:=false
end;
end;
if i=2 then i:=3 else inc(i,2);
until (i>p) or (not flag);
writeln('Число M равно ',m)
end
else
writeln('Число M не существует.');
write('Продолжить ? (y/n) ');
repeat
while keypressed do ch:=readkey;
ch:=readkey;
case ch of
'Y','y': writeln('y');
'N','n': begin writeln('n'); exit end
end;
until ch in ['N','n','Y','y'];
end;
end.
{ Описание задачи.
Если взять два любых натуральных числа a и b, то a будет делиться на b, если все степени множителей при разложении числа a на простые множители больше либо равны аналогичных степеней, получаемых при разложении числа b.
Пример :
120 = 2*2*2 * 3 * 5
40 = 2*2*2 * 5
120 делится на 40
Следовательно, n! делится на p в степени m, если степень любого простого число mn (2<=mn<=p) в разложении числа n! на простые множители больше, чем в аналогичном разложении числа p в степени m.
Если F(i,p) - степень простого числа i в разложении числа p на простые множители, то F(i,pm)=F(i,p)*m.
Отсюда алгоритм решения :
Степень m будет равна целой части от минимального отношения степени простого числа i в разложении n! к степени числа i в разложении числа p, где 2<=i<=p.
Алгоритм разложения числа р на простые множители достаточно
прост. Основную трудность представляет алгоритм разложения числа n!.
алгоритм степень_простого_числа_в_разложении_числа_n! (нат n,mn,s,k)
дано n,mn
надо s
нач
s:=0
k:=mn
пока [n/k]>0
нц
s:=s+[n/k]
k:=k*mn
кц
кон.
[Назад]
Решение задачи 23.
Воспользуемся тем, что для n>=4 выполняется неравенство n<=(n-2)*2, т.е. разбивать число на слагаемые, большие 3, не имеет смысла. Выделяем из числа n слагаемые-двойки, пока не получим остаток меньший либо равный 3 (остаток может быть либо 3, либо 2). Так как 2*2*2<3*3, то заменим каждые три двойки на две тройки. По лученное разложение и является искомым.
Разберите самостоятельно случаи
1) когда необходимо максимизировать произведение, и слагаемые в разложении числа n должны принадлежать промежутку [A,B], A и B вводятся пользователем.
2) когда необходимо минимизировать произведение, и слагаемые в разложении числа n должны принадлежать промежутку [A,B], A и B вводятся пользователем.
[Назад]
Решение задачи 24.
Если S>=4 то существуют единственные S1 и S2, такие что
S=S1*S2=S1+S2.
Более того, наименьшее из S1 и S2 больше 1 и <=2:
S1=(S/2, S2=(S+)/2,
(S-4)2=S2-8*S+16<=S2-4*S<(S-2)2
и
1<S1=(S-)/2<=2.
Итак, если r<4 то разложение на множители закончено, иначе проводим разложение r на два множителя, один из них <=2 (и тем более <4 ), если другой <4 , то процесс закончен, иначе повторяем факторизацию S до тех пор, пока не получим искомое разложение.
[Назад]
Решение задачи 25.
Из теоремы Виета получаем, что X1*x2*x3*x4*x5=-A(0)/A(5),
откуда следует, что число xi должно быть делителем A(0)/A(5). Находим все делители A(0)/A(5)=R (Если A(0)=A(1)=...=A(i)=0, то i+1 корень уравнения равен 0. Мы делим уравнение на x(i+1), дальше ищем делители числа r=A(i+1)/A(5)).
i:=1;
пока i<=R повторять
если R делится нацело на i
то проверить, являются ли числа +i
и -i корнями полинома
i:=i+1
конец пока
[Назад]
Решение задачи 26.
Пусть m/n - текущая несократимая дробь. Покажем, как найти следующую по значению дробь. Понятно, что она будет среди несокра тимых дробей вида k/р, где р может принимать значения от 2 до 15. Учитывая условие k/р > m/n можно для каждого р прямо вычислять ми нимальное значение k следующим образом:
k=m*p/n+1.
При этом каждая дробь k/р, полученная описанным выше образом, несократима.
m:=0; n:=1
Повторять
i:=1; j:=1;
для р:=2 до 15 выполнять
нц
k:=m*p div n + 1;
если k*j < p*i
то i:=k; j:=p;
все
кц
m:=i; n:=j;
пока i>=j
[Назад]
Решение задачи 27.
Это условие - равенство нулю суммы всех чисел. Мы всегда можем "перетащить" с помощью последовательности ходов все ненулевые числа, помечающие вершины, в одну какую-либо вершину. Если сумма всех чисел равна 0, то после этих ходов окажется, что во всех вершинах записан 0.
[Назад]
Решение задачи 28.
а). Программа вычисления следующая:
P:=a[N]
for i:=N-1 downto 0 do
P:=P*x+a[i];
Посмотрите, как эта схема работает, вручную найдя значение полинома по его коэффициентам и точке x.
b). Решается аналогично.
[Назад]
Решение задачи 29.
Продемонстрируем метод нахождения коэффициентов полинома на примере возведения p(x)=(x2+2*x+1) в четвертую степень.
Будем последовательно возводить полином в степени 2, 3,4.
Для второй степени справедливо равенство p(x)*p(x)=(x2+2x+1)*(x2+2x+1)=(x2+2x+1)*x2+ +(x2+2x+1)*2x+(x2+2x+1)*1
Будем складывать коэффициенты у одинаковых степеней x, выписывая коэффициенты полинома первой степени с соответствующим сдвигом и умножаем на коэффициент:
x4 |
x3 |
x2 |
x1 |
x0 |
|
|
|
1 |
2 |
1 |
x2+2x+1 |
|
2 |
4 |
2 |
|
(x2+2x+1)*2x |
1 |
2 |
1 |
|
|
(x2+2x+1)*x2 |
1 |
4 |
6 |
4 |
1 |
|
Получили коэффициенты второй степени полинома. Для третьей степени, поступая аналогично, получаем такую таблицу:
X6 |
x5 |
x4 |
x3 |
x2 |
x1 |
x0 |
|
|
|
1 |
4 |
6 |
4 |
1 |
p(x)*p(x) |
|
2 |
8 |
12 |
8 |
2 |
|
2x*p(x)*p(x) |
1 |
4 |
6 |
4 |
1 |
|
|
x2*p(x)*p(x) |
1 |
6 |
15 |
20 |
15 |
6 |
1 |
|
Коэффициенты 4-ой степени:
x8 |
x7 |
x6 |
x5 |
x4 |
x3 |
x2 |
x1 |
x0 |
|
|
1 |
6 |
15 |
20 |
15 |
6 |
1 |
|
2 |
12 |
30 |
40 |
30 |
12 |
2 |
|
1 |
6 |
15 |
20 |
15 |
6 |
1 |
|
|
1 |
8 |
28 |
56 |
70 |
56 |
28 |
8 |
1 |
С произвольным полиномом поступаем так же: последователь-но находим степени 2,3, ..., m. Когда мы знаем коэффициенты полинома в степени i, то вычисляем коэффициенты степени i+1,
выписывая со сдвигом коэффициенты полинома степени i, умноженные на соответствующие коэффициенты исходного полинома, а затем складываем их в столбик.
[Назад]
Решение задачи 30.
Решается аналогично предыдущей задаче. Рассмотрите полином
p(x)=(x-A[1])*...*(x-A[N])
и вычислите его коэффициенты. На каждом из шагов, в отличие от предыдущей задачи, умножение будет производиться на новый одночлен (x-A[i]).
[Назад]
Решение задачи 31.
Рассмотрим следующую задачу:
Разделить полином p(x)=a[n]*xn + ... + a[1]*x+a[0] на v(x)=(x-d), т.е. найти такую константу - остаток r и такое частное s(x)=s[n-1]*x(n-1)+ ... + s[1]*x+s[0], что
p(x)=s(x)(x)+r.
Делить будем в столбик. Рассмотрим операцию деления полиномов на примере:
3x2+2x+5 x-2
3x2-6x ..3x+8
....8x+5
....8x-16
.......21
Тут r=21, s(x)=3x+8.
Видно, что коэффициент s[n-1] при старшей степени x в s равен коэффициенту при старшей степени x в p, а остальные коэффициенты в s находятся по формулам:
s[t-1]=(-d)*s[t]+p[t];
r=(-d)*s[0]+p[0].
В наглядной форме это можно записать в виде так называемой схемы Горнера:
Тогда проведенное выше деление можно записать в следующем виде:
Вернемся к исходной задаче. Приравняем полиномы: p0(x)=a[n]*xn+a[n-1]*x(n-1)+ ... +a[1]*x+a[0]=
=b[n](x-d)n+ ... +b[1]*(x-d)+b[0].
Находим остаток от деления полиномов справа и слева от знака равенства на (x-d). Слева все слагаемые, кроме последнего, делятся на (x-d) нацело. Поэтому
P0(x)=(x-d)*p1(x)+b[0].
Получаем, что
P1(x)=b[n]*(x-d)(n-1)+ ... +b[2]*(x-d)+b[1].
Аналогично находим b[1]:
P1(x)=(x-d)*p2(x)+b[1],
затем по p2(x) определяем b[2], и т.д., пока не найдем b[n].
Особенно удобно это записывается в виде схемы Горнера (обратите внимание, что в верхней строке записаны коэффициенты p0, то, что получается в строке ниже - это коэффициенты p1, к которым также можно применить схему Горнера, находя коэффициенты p2, и т.д.)
Пример: p(x)=3x2+2x+5, d=-2,
Получаем
3x2+2x+5=3(x-2)2+14(x-2)+21.
[Назад]
Решение задачи 32.
Пусть f(x)=ax4+bx3+cx2+dx+e. Выразим f(x+1) через f(x):
f(x+1)=f(x)+(4ax3+(6a+3b)x2+(4a+3b+2c)x+(a+b+c+d)=f(x)+g(x),
где
g(x)=Ax3+Bx2+Cx+D.
Поступим аналогично и с g(x): g(x+1)=g(x)+(3Ax2+(3A+2B)x+(A+B+C))=g(x)+h(x), где h(x)=A'x2+B'x+C'.
Далее:
h(x+1)=h(x)+(2A'x+(A'+B'))=h(x)+p(x),
где
p(x)=A"x+B". p(x+1)=p(x)+A".
Имеем:
f(x+4)=f(x+3)+g(x+3)
g(x+3)=g(x+2)+h(x+2)
h(x+2)=h(x+1)+p(x+1)
p(x+1)=p(x)+A".
Отсюда получаем фрагмент программы:
< BLOCK 1 >
x:=5;
repeat
P:=P+A2;
H:=H+P;
G:=G+H;
F:=F+G;
writeln(x,F);
x:=x+1;
until x=10001;
Итак, на каждое значение, начиная с 5, тратится 5 операций сложения. Остается около 1000 операций на вычисление f(1), f(2), f(3), f(4), для инициализации
P:=p(1); H:=h(2); G:=g(3); (F:=f(4));
и на вычисление A2:=A". Ясно, что 1000 операций хватит на все эти вычисления.
[>]
|