Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
mybook11.05.12.doc
Скачиваний:
8
Добавлен:
01.07.2025
Размер:
6.22 Mб
Скачать

Длинная арифметика

Если количество цифр натурального числа не позволяет записать его в каком-нибудь базовом типе Паскаля или Дельфи, то приходится хранить цифры числа в одномерном массиве. Для удобства будем хранить цифры числа в обратном порядке.

В каждом элементе массива будет храниться одна цифра.

В длинной арифметике решаются следующие классические задачи:

  • Считывание длинного числа из файла.

  • Запись длинного числа в файл.

  • Сложение двух длинных чисел

  • Вычитание двух длинных чисел

  • Умножение длинного числа на короткое в системе счисления с основанием 10.

  • Умножение длинного числа на длинное.

  • Деление длинного на короткое

  • Деление длинного на длинное

  • Дано натуральное число N. Найти последнюю ненулевую цифру числа N!

  • Даны натуральные числа N и M. Найти последнюю ненулевую цифру числа сочетаний C из N по M.

  • Даны натуральные числа N и M. Вычислить число сочетаний C из N по M.

  • Найти все натуральные числа, не превосходящие данного натурального N, десятичная запись которых есть строго убывающая или строго возрастающая числовая последовательность.

Задача 22 Сложение двух длинных чисел

Слагаемые будем хранить в двух одномерных массивах, записывая их в обратном порядке.

program sloj2dl;

const nmax=100;

var a,b,c:array[0..nmax] of longint; a,b- слагаемые, с- результат

n:longint;

cod,kol:integer;

s:string;

procedure init; процедура считывания двух длинных чисел и

var i,t:integer; запись их в массивы a и b в обратном порядке

begin

fillchar(a,sizeof(a),0); очищаем массивы

fillchar(b,sizeof(b),0);

fillchar(c,sizeof(c),0);

assign(input,'input.txt');

reset(input);

readln(s); считываем первое число в виде строки

t:=0;

for i:=length(s) downto 1 do

begin

inc(t);

val(s[i],a[t],cod); переводим изображение цифры в числовой

формат и записываем в массив а

end; заносим ее в массив а

a[0]:=t; запоминаем количество элементов массива а

readln(s); считываем второе число в виде строки

t:=0;

for i:=length(s) downto 1 do

begin

inc(t);

val(s[i],b[t],cod); переводим изображение цифры в числовой формат

и записываем в массив b

end;

b[0]:=t; запоминаем количество элементов массива b

close(input);

end;

function max2(x,y:integer):integer; функция находит максимальное из двух чисел

begin

if x>y then max2:=x else max2:=y;

end;

procedure out; вывод результата

var i:integer;

begin

assign(output,'output.txt');

rewrite(output);

for i:=c[0] downto 1 do

write(c[i]);

close(output);

end;

procedure solve; процедура сложение двух длинных чисел

var um,i:integer;

begin

kol:=max2(a[0],b[0]); находим максимальную длину слагаемых

um:=0;

for i:=1 to kol do

begin

c[i]:=(a[i]+b[i]+um) mod 10; складываем цифры чисел поразрядно

um:=(a[i]+b[i]+um) div 10; запоминаем цифру переноса в уме

end;

if um<>0 then если в уме не ноль, то

begin inc(kol);c[kol]:=um end; увеличиваем количество цифр на 1 и

переносим цифру

c[0]:=kol; запоминаем количество цифр результата

end;

begin init; solve; out; end.

задачи

Задача 23 Умножение длинного числа на короткое

В отличие от программы сложения двух длинных чисел, в программе умножения мы не будем хранить количество цифр сомножителей и результата, а просто при выводе пропустим незначащие первые нули. Так можно было делать и в предыдущей программе. Длинное число записываем в массив в обратном порядке.

program umndlonkor;

const nmax=100;

var a,c:array[1..nmax] of longint;

n,b:longint;

cod:integer;

s:string;

procedure init;

var i,t:integer;

begin

fillchar(a,sizeof(a),0);

fillchar(c,sizeof(c),0);

assign(input,'input.txt');

reset(input);

readln(s); считываем длинное число, заданное в виде строки

t:=0;

for i:=length(s) downto 1 do

begin

inc(t);

val(s[i],a[t],cod);

end;

read(b); считываем короткое число

close(input); end;

procedure out; вывод результата

var i,j:integer;

begin

assign(output,'output.txt');

rewrite(output);

for i:=c[0] downto 1 do

write(c[i]);

close(output);

end;

procedure solve;

var um,i:integer;

begin

um:=0;

for i:=1 to a[0] do бежим по массиву цифр с конца данного числа

begin

c[i]:=(a[i]*b+um) mod 10; записываем последнюю цифру в результирующий массив

um:=(a[i]*b+um) div 10; запоминаем количество десятков в um

end;

while um>0 do помещаем оставшиеся цифры из числа в уме в массив с

begin

inc(c[0]);

c[c[0]]:=um mod 10;

um:=um div 10;

end;

end;

begin init; solve; out; end.

задачи

Задача 24 Умножение длинного числа на длинное

program umn2dl;

const nmax=100;

var a,b,c:array[0..nmax] of longint; a,b- множители, с- произведение

dv,i,j,t,cod:integer;

s:string;

procedure init; считывание двух длинных чисел и

var i,t:integer; запись их в массивы a и b в обратном порядке

begin

fillchar(a,sizeof(a),0); очищаем массивы

fillchar(b,sizeof(b),0);

fillchar(c,sizeof(c),0);

assign(input,'input.txt');

reset(input);

readln(s); считываем первое число

t:=0;

for i:=length(s) downto 1 do

begin

inc(t);

val(s[i],a[t],cod); переводим изображение цифры в числовой

формат и записываем в массив а

a[0]:=t; запоминаем количество элементов массива a

end;

readln(s); считываем второе число

t:=0;

for i:=length(s) downto 1 do

begin

inc(t);

val(s[i],b[t],cod); переводим изображение цифры в числовой

формат и записываем в массив b

b[0]:=t; запоминаем количество элементов массива b

end;

close(input);

end;

procedure out; вывод результата

var i,j:integer;

begin

assign(output,'output.txt');

rewrite(output);

i:=nmax;

while c[i]=0 do dec(i); пропускаем незначащие нули

for j:=i downto 1 do выводим значащие цифры

write(c[j]);

close(output);

end;

Procedure Solve;

Begin

for i:=1 to a[0] do

for j:=1 to b[0] do

begin

dv:=longint(a[i]*b[j]+c[i+j-1]); longint предохраняет от переполнения

тип integer

inc(c[i+j],dv div 10);

c[i+j-1]:=dv mod 10;

end;

end;

Begin init; solve; out; End.

задачи

Задача 25 Деление двух длинных чисел

Var i,l,r,t,x,j: LongInt;

begin

FillChar(C, SizeOf(C), 0);

FillChar(D, SizeOf(D), 0);

If A[0]< B[0] then D:= A

else begin

t:= A[0]-B[0];

For i:= A[0] downto t+1 do

B[i]:= B[i-t];

For i:= t downto 1 do

B[i]:= 0;

B[0]:= A[0]; C[0]:= t+1;

For i:= t+1 downto 1 do begin

l:= 0; r:= 10000;

While r-l> 1 do begin

x:= (l+r) div 2;

MulNum(B, x, D);

If Less(D, A) then l:= x

else r:= x;

end;

MulNum(B, l, D);

C[i]:= l;

Sub(A, D, A);

For j:= 2 to B[0] do

B[j-1]:= B[j];

B[B[0]]:= 0; Dec(B[0]);

end;

D:= A;

end;

end;

задачи

Задача 26 Равны ли два длинных числа

program eqtowlong;

const nmax=255;

type Tlong=array[0..nmax] of integer;

var a,b:Tlong;

n:longint;

cod:integer;

s:string;

function Eq(a,b:Tlong):boolean;

var i:integer;

begin

Eq:=false;

if a[0]<>b[0] если длины чисел не равны, то выходим

then exit из функции

else

begin

i:=1;

while (i<=a[0])and(a[i]=b[i])

do inc(i); сравниваем цифры чисел

end;

if i=a[0]+1 then EQ:=TRUE; если все цифры просмотрели то числа равны

end;

procedure init; считываем длинные числа и записываем их в

массив

var i,t:integer;

begin

fillchar(a,sizeof(a),0);

fillchar(b,sizeof(b),0);

assign(input,'input.txt');

reset(input);

readln(s);

a[0]:=length(s);

t:=1;

for i:=length(s) downto 1 do

begin

val(s[i],a[t],cod);

inc(t);

end;

readln(s);

b[0]:=length(s);

t:=1;

for i:=length(s) downto 1 do

begin

val(s[i],b[t],cod);

inc(t);

end;

close(input);

end;

procedure out;

var i,j:integer;

begin

assign(output,'output.txt');

rewrite(output);

if Eq(a,b)

then write('YES')

else write('NO');

close(output);

end;

begin init; out; end.

задачи

Задача 27 Больше ли первое длинное число второго

program moretowlong;

const nmax=255;

type Tlong=array[0..nmax] of integer;

var a,b:Tlong;

n:longint;

cod:integer;

s:string;

function More(a,b:Tlong):boolean;

var i:integer;

begin

More:=false;

if a[0]<b[0] если количество цифр в первом числе меньше,

then exit чем во втором то выходим. Значение функции false

else

if a[0]>b[0] если больше

then

begin More:=true; exit end выходим, значение функции true

else если количество цифр одинаково

begin

i:=a[0];

while (i>0)and(a[i]=b[i])

do dec(i); сравниваем цифры чисел

if i=0 then exit если все цифры равны, то выходим.

Else значение функции false

if a[i]>b[i] хотя бы одна цифра первого числа больше цифры второго

then More:=true; то выходим. Значение функции true

end;

end;

procedure init; числа записываются в массивы в обратном порядке

var i,t:integer;

begin

fillchar(a,sizeof(a),0);

fillchar(b,sizeof(b),0);

assign(input,'input.txt');

reset(input);

readln(s);

a[0]:=length(s);

t:=1;

for i:=length(s) downto 1 do

begin

val(s[i],a[t],cod);

inc(t);

end;

readln(s);

b[0]:=length(s);

t:=1;

for i:=length(s) downto 1 do

begin

val(s[i],b[t],cod);

inc(t);

end;

close(input);

end;

procedure out;

var i,j:integer;

begin

assign(output,'output.txt');

rewrite(output);

if More(a,b)

then write('YES')

else write('NO');

close(output);

end;

begin init; out; end.

задачи

Задача 28 Вычисление 2n

Так как 2n=2n-1*2 , то промежуточный результат, равный 2n-1 ,будем хранить как длинное число, а 2 как короткое. Применяем многократно алгоритм умножения длинного числа на короткое.

Program dvavn;

const nmax=100;

var a,c:array[1..nmax] of longint;

n,b:longint;

procedure init;

var i,t:integer;

begin

assign(input,'input.txt');

reset(input);

read(n); считываем n

close(input);

fillchar(a,sizeof(a),0);

a[1]:=1; записываем 1 в массив а

b:=2; короткое число

end;

procedure out;

var i,j:integer;

begin

assign(output,'output.txt');

rewrite(output);

i:=nmax;

while c[i]=0 do dec(i); пропускаем первые нули

for j:=i downto 1 do

write(c[j]); выводим значащие цифры

close(output);

end;

procedure solve;

var um,i,j:integer;

begin

for j:=1 to n do

begin

fillchar(c,sizeof(c),0); обнуляем массив с

um:=0;

for i:=1 to nmax do вычисляем 2n

begin

c[i]:=(a[i]*b+um) mod 10;

um:=(a[i]*b+um) div 10;

end;

a:=c; копируем массив с в массив а

end

end;

begin init; solve; out;end.

задачи

Задача 29 N- е число Фибоначчи

Найти N-е число Фибоначчи.

Числами Фибоначчи называется последовательность натуральных чисел полученная следующим образом: первые два числа этой последовательности равны единице, а все последующие элементы равны сумме двух предыдущих. a1=1, a2=1, an= an-1+ an-2 при n>2.

1,1,2,3,5,8…-последовательность чисел Фибоначчи

В XIII веке итальянский математик Леонардо Фибоначчи исследовал решение следующей задачи:

Фермер выращивает кроликов. Когда кролик становится взрослым (ему исполняется два месяца), то каждый месяц он дает потомство в одного кролика. Сколько кроликов будет у фермера через n месяцев, если сначала у него был только один (считается, что кролики не умирают и дают потомство по выше описанной схеме)?

Очевидно, что в начале первого и второго месяца у фермера один кролик, поскольку потомства еще нет. На третий месяц будет два кролика. На четвертый месяц первый кролик даст еще одного, а второй потомства не даст, так как ему еще один месяц. Таким образом на четвертый месяц будет три кролика.

Количество кроликов в n - ый месяц будет равно количеству кроликов, которое было в n – 1 месяце, плюс количество родившихся. Последних будет столько, сколько кроликов дают потомство (которым уже исполнилось 2 месяца). Их число равно количеству кроликов в n – 2 месяц.

Если через Fn обозначить количество кроликов после n - го месяца, то имеет местоследующее рекуррентное соотношение:

 

Fn =  Fn-1 + Fn-2, F1 = F2 = 1

Положим F0 = 0, при этом соотношение при n = 2 останется истиным. Таким образом образовалась последовательность

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... ,

которая называеться последовательностью Фибоначчи.

 

Максимальным числом Фибоначчи, которое помещается в тип int, является F46 = 1836311903. В 64-битовый целочисленный тип int64 помещается максимум F92. Если в задаче требуется находить значения f(n) для n > 92, то следует воспользоваться длинной арифметикой.

В случае необходимости запоминания всех чисел Фибоначчи f(1), f(2), …, f(n), заведем массив m, в котором положим m[i] = f(i), 0 < i <= n. Реализация может быть как циклическая, так и рекурсивная с запоминанием:

Формула Бине выражает в явном виде значение Fn как функцию от n:

Fn =  = ,

где  – золотое сечение. При этом  и  (-)-1 = 1 –  являются корнями квадратного уравнения x2x – 1 = 0.

Следствие. Для всех n > 0 имеет место равенство: Fn = .

 

Наибольший общий делитель двух чисел Фибоначчи равен числу Фибоначчи с индексом, равным наибольшему общему делителю индексов, то есть

НОД(Fn, Fm) = FНОД(n,m)

Следствие 1. Fm делится на Fn тогда и только тогда, когда m делится на n (за исключением n = 2).

Следствие 2. Fn может быть простым только для простых n (за исключением n = 4).

 

Упражнение 1.1. Свойства чисел Фибоначчи. Доказать следующие свойства:

а) F0 + F1 + F2 + F3 + … +  Fn = Fn+2 – 1;

б) F1 + F3 + F5 + … +  F2n-1 = F2n;

в) F0 - F1 + F2 - F3 + … - F2n-1 +  F2n = F2n-1 – 1;

г) F02 + F12 + F22 + F32 + … +  Fn2 = Fn * Fn+1;

д) Fn+1Fn-1 – Fn2 = (-1)n (Равенство Ж. Д. Кассини);

е) Fn+m = Fm Fn+1 + Fm-1 Fn;

 

program nchislofibonachi;

const nmax=20000;

var a,b,c:array[1..nmax] of byte;

n:longint;

procedure init;

var i,t:integer;

begin

assign(input,'input.txt');

reset(input);

read(n);

close(input);

fillchar(a,sizeof(a),0);

fillchar(b,sizeof(b),0);

a[1]:=1; b[1]:=1; заносим первые два числа Фибоначчи в

массивы a и b

end; числа записываются в обратном порядке

procedure out; вывод результата

var i,j:integer;

begin

assign(output,'output.txt');

rewrite(output);

i:=nmax;

while c[i]=0 do dec(i); пропускаем незначащие нули

for j:=i downto 1 do выводим значащие цифры

write(c[j]);

close(output);

end;

procedure solve;

var um,i,j:integer;

begin

if (n=1)or(n=2) then

begin c[1]:=1;out end; если n=1 или n=2 печатаем 1

for j:=3 to n do последовательно складываем числа Фибоначчи

begin

fillchar(c,sizeof(c),0); обнуляем массив с

um:=0; в уме 0

for i:=1 to nmax do последовательно складываем цифры чисел

begin

c[i]:=(a[i]+b[i]+um) mod 10; последнюю цифру записываем в массив с

um:=(a[i]+b[i]+um) div 10; количество десятков запоминаем в um

end;

a:=b; перебрасываем массив b в a

b:=c; перебрасываем массив c в b

end

end;

begin init; solve; out;end.

задачи

Задача 30 Вычисление N-факториал

Дано натуральное число N. Вычислить N!

Опр. Эн- факториалом натурального числа N называется произведение натуральных чисел 1*2*…*N и обозначается N!

program nfaktorial;

const nmax=100;

var a,c:array[1..nmax] of longint;

n,b:longint;

procedure init;

var i,t:integer;

begin

assign(input,'input.txt');

reset(input);

read(n); считываем n

close(input);

fillchar(a,sizeof(a),0);

a[1]:=1; записываем 1 в массив а

end;

procedure out;

var i,j:integer;

begin

assign(output,'output.txt'); rewrite(output);

i:=nmax;

while c[i]=0 do dec(i); пропускаем первые нули

for j:=i downto 1 do

write(c[j]); выводим значащие цифры

close(output);

end;

procedure solve;

var um,i,j:integer;

begin

for j:=1 to n do

begin

fillchar(c,sizeof(c),0); обнуляем массив с

um:=0;

for i:=1 to nmax do вычисляем n!

begin

c[i]:=(a[i]*j+um) mod 10;

um:=(a[i]*j+um) div 10;

end;

a:=c;

end

end;

begin init; solve; out;end.

задачи

Задача 31 К-я цифра

Дано натуральное число К. Найти К-ю цифру последовательности 492549121..., в которой выписаны подряд квадраты всех простых чисел в порядке возрастания.

Входной файл Input.txt

содержит одно натуральное число К (1<=К<=90000).

Выходной файл Output.txt

содержит одну цифру, стоящую на К-м месте в последовательности.

Примеры:

Input.txt

Output.txt

1

4

4

5

program ksimplekvadrat;

const nmax=100000;

p:array[1..13848] of longint=

(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,

53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,

127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,

………………………………………………………………………………………………………………………………………..

149551,149561,149563,149579,149603,149623,149627,149629,149689,149711,149713,149717,149729,149731,149749,149759,149767,149771,149791,149803,149827,149837,149839,149861,149867,149873,149893,149899,149909,149911,149921,149939,149953,

149969,149971,149993);

var

a,t,i,n,k,j:longint;

procedure init;

begin

assign(input,'input.txt'); reset(input);

read(k);

close(input);

end;

function kolcifr(n:longint):longint; находит количество цифр числа

var kol:longint;

begin

kol:=0;

while n>0 do

begin

inc(kol);

n:=n div 10;

end;

kolcifr:=kol;

end;

procedure solve;

begin

assign(output,'output.txt'); rewrite(output);

i:=0;t:=0;

while i<k do пока цифр в ряду простых чисел меньше к

begin

inc(t); считаем простые числа

a:=p[t]*p[t];

i:=i+kolcifr(a); считаем цифры простых чисел

end;

for j:=1 to i-k do отрезаем от последнего числа лишние цифры

a:=a div 10;

write(a mod 10); выводим последнюю цифру

close(output);

end;

begin init; solve; end.

задачи

Задача 32 Кузнечик

Кузнечик прыгает по плоскости так, что его координаты на плоскости – всегда целые числа, длина прыжка равна 1, а каждый следующий прыжок (начиная со второго) повернут к предыдущему на 90 градусов по выбору кузнечика. Найти за какое наименьшее число прыжков из точки (0,0) кузнечик может попасть в точку (X,Y).

Входные данные:

В строке числа X и Y (по модулю не больше 10000).

Выходные данные:

Найденное наименьшее количество прыжков

Пример:

Input.txt

Output.txt

2 3

5

var x,y,n,h:integer; n-количество прыжков

begin h-высота на которую кузнечик должен

сначала забраться

read(x,y);

if x<0 then x:=abs(x); конечный пункт помещаем в первую

четверть

if y<0 then y:=abs(y); выше биссектриссы 1 и 3

координатных углов

if y<x then begin h:=y;y:=x;x:=h;end;

if (x=y)or(y-x=1)then n:=x+y если можно добраться по простой ломаной

else

begin

n:=2*x; если нельзя, то убираем квадрат сверху

h:=y-x; и поднимаемся вверх

if h mod 2=0

then n:=n+2*h

else n:=n+2*h-1;

end;

writeln(n);

end.

задачи

Задача 33 Наибольшее число нет решения

Дана последовательность натуральных чисел. Найти в ней наибольшее число, сумма цифр соседей которого есть простое число (у первого и последнего по одному соседу). Если таких чисел нет, то вывести –1.

Входной файл Input.txt содержит:

  • в первой строке одно натуральное число N (N100000).

  • во второй строке N натуральных чисел , записанных через пробел а12,…аni106).

Выходной файл Output.txt должен содержать одно натуральное число.

Пример:

Input.txt

Output.txt

5

4 6 7 9 3

6

задачи

Задача 34 Найти последнюю ненулевую цифру n! (1<=n<=1000000)

Если задачу решать в лоб, то решение возьмет около трети баллов. В нашем решении мы учитываем, что последние нули в результате получаются при умножении 2 на 5.

program lastcifrafact;

var n,res,k2,k5,p,i:longint;

procedure init;

begin

assign(input,'input.txt');

reset(input);

read(n);

close(input);

k2:=0;k5:=0;p:=1;res:=1;

end;

procedure out;

begin

assign(output,'output.txt');

rewrite(output);

write(res mod 10);

close(output);

end;

procedure solve;

begin

if n=1 then begin res:=1;out;halt(0) end; частный случай n=1

for i:=2 to n do перебираем все множители 1*2*3*4*…n

begin

p:=i; делаем копию i

while p mod 2 =0 do

begin

p:=p div 2;

inc(k2); находим количество двоек в i

end;

while p mod 5 =0 do

begin

p:=p div 5;

inc(k5); находим количество пятерок в i

end;

res:=(res*(p mod 10)) mod 10; находим последнюю цифру

произведения 1*2…i

end;

case (k2-k5) mod 4 of так как 2 больше чем 5, а 10 получается

0: res:=res*6; при умножении 2 на 5, то двоек останется

1: res:=res*2; k2-k5.Степени 2 на последнюю цифру

имеют период 4.

2: res:=res*4; Последние цифры степеней 2 есть

3: res:=res*8; 2,4,8,6 ,2,4,8,6…

end;

end;

begin init; solve; out; end.

задачи

Опр.Натуральное число называется совершенным, если оно равно сумме всех своих делителей, не считая его самого.

Задача 35 Найти все совершенные числа, меньшие, чем заданное М

Program sovnumbers;

var s,m,n,i:integer;

begin

writeln('input number');

read(m);

for n:=2 to m-1 do полный перебор

begin

s:=1;

for i:=2 to n div 2 do

if n mod i=0 then inc(s,i); если n делится на I, то прибавляем делитель

if s=n then writeln(s); если сумма делителей равна числу то число

выводим

end;

end.

задачи

Задача 36 Сломанный калькулятор

У калькулятора есть две ячейки памяти: содержимое первой из них всегда отображается на табло, вторая является буфером. В начальный момент времени на табло калькулятора отображается целое число X, а в буфере записано число 0. У калькулятора работают только две клавиши: «+» и «=». При нажатии на «+» число, которое в данный момент отображено на табло, копируется в буфер. При нажатии на «=» число из буфера прибавляется к числу, отображенному на табло, и результат отображается на табло, число в буфере при этом не меняется.

Требуется за наименьшее число нажатий клавиш на калькуляторе добиться того, чтобы на табло было отображено число Y.

Формат входных данных

Входной файл содержит два целых числа X и Y. Каждое из этих чисел по модулю не превышает 109.

Формат выходных данных

В первую строку выходного файла выведите одно число — количество нажатий клавиш, которое потребуется для получения числа Y. Если из числа X получить число Y с помощью указанных операций невозможно, в выходной файл выведите одно число –1.

Примеры

Input.txt

Output.txt

Пояснение (ответ дает следующая последовательность нажатий)

1 1

0

–2 –6

3

+==

1 8

6

+===+=

2 5

-1

Program calk;

const

p:array[1..3638] of longint= создаем массив простых чисел-

(2,3,5,7,11,13,17,19,23,29, возможных делителей Y

31,37,41,43,47,53,59,61,67,71,

73,79,83,89,97,101,103,107,109,113,

127,131,137,139,149,151,157,163,167,173,

3751,33757,33767,33769,33773,33791,33797,

33809,33811,33827,33829,33851,33857,33863,33871,33889,33893,

33911,33923,33931,33937,33941,33961,33967,33997);

Делители встречаются попарно и наибольший делитель из наименьших в парах

не превышает квадратного корня из N

Var

x,y,res,i: longInt;

log:boolean; признак того, что X является делителем Y

procedure init;

begin

assign(input,'b.in');

reset(input);

read(x);read(y);

close(input);

end;

procedure out;

begin

assign(output,'b.out');

rewrite(output);

write(res);

close(output);

end;

Procedure Solve;

Begin

res:=0;log:=true;

if x=y then begin res:=0; out;halt(0) end; если числа равны

if ((x<>0)and(y=0)) then begin res:=-1; out;halt(0) end; если Х не равен нулю,а

Y равен нулю

if ((x=0)and(y<>0)) then begin res:=-1; out;halt(0) end; если Y не равен нулю,а

Х равен нулю

if ((x div abs(x)) *(y div abs(y))<0)or если у данных чисел

разные знаки

(y mod x<>0) then begin res:=-1; out;halt(0) end;

x:=abs(x);y:=abs(y);y:=y div x; x:=1; делим Y на X и принимаем

X равным 1

For i := 1 To 3638 Do пробегаем массив простых

чисел и делим Y на

p[i],пока делится

while y mod p[i]=0 do

begin inc(res,p[i]); y:=y div p[i]; log:=false end;

if log then res:=y; если Y число простое

End;

Begin init; solve; out; End.

задачи

Задача 37 Счастливый билет (Вариант с использованием массива)

Каждый мечтает хоть раз в жизни выиграть в лотерею. Но, увы, везет не всем. Однажды один такой невезучий загадал, что, если он хоть раз купит счастливый билет, то обязательно произойдет чудо и жизнь его переменится к лучшему. И вот он покупает билет, но билет несчастливый. Лихорадочно он начал покупать следующие билеты из пачки, номера их шли подряд в порядке возрастания. Сколько билетов придется ему докупить, чтобы чудо все-таки произошло?

Примечание:

  • билет назовем счастливым, если он содержит четное число цифр и сумма цифр левой половины числа равна сумме цифр правой

  • первые цифры могут быть нулями

Входной файл Input.txt содержит: одно натуральное число К с четным количеством цифр (цифр не более 8).

Выходной файл Output.txt содержит одно натуральное число – равное количеству докупленных билетов.

Примеры:

Input.txt

Output.txt

32

1

0999

2

Program happy;

var kol,res:integer;

log:boolean;

a:array[1..8] of integer;

function prov:boolean; проверяет число на “счастливость”

var s1,s2,i:integer;

begin

prov:=false;s1:=0;s2:=0;

for i:=1 to kol div 2 do

s1:=s1+a[i];

for i:=kol div 2+1 to kol do

s2:=s2+a[i];

if s1=s2 then prov:=true;

end;

procedure init;

var i,cod,n:integer;

c:char;

begin

assign(input,'input.txt');reset(input);

i:=0;

while not eof do

begin

read(c); считываем по одному символу

val(c,n,cod); переводим в число

inc(i);

a[i]:=n; записываем в массив

end;

kol:=i; запоминаем количество цифр

close(input);

end;

procedure out;

begin

assign(output,'output.txt');

rewrite(output);

write(res);

close(output);

end;

procedure next; прибавляет 1 к текущему числу

var i:integer;

begin

if a[kol]<>9 если последняя цифра не 9

then inc(a[kol]) увеличиваем ее на 1

else иначе

begin

i:=kol; бежим по числу справа налево и все 9

заменяем 0

while (i>1)and(a[i]=9) do

begin

a[i]:=0; dec(i);

end;

inc(a[i]); первую не 9 увеличиваем на 1

end;

end;

procedure solve;

begin

res:=0;

repeat

log:=prov; проверяет число на “счастливость”

if log then exit; если счастливое, то выходим из процедуры

next; иначе переходим к следующему числу

inc(res); увеличиваем результат на 1

until log;

end;

begin init; solve; out; end.

задачи

Задача 38 Счастливый билет (вариант без использования массива)

Program happy;

var kol,res,s1,s2:longint;

log:boolean;

n,i,koln:longint;

s:string;

cod:integer;

function prov(num:longint):boolean; проверяет билет на “счастливость”

var i,m:longint;

begin

s1:=0;s2:=0;prov:=false;

for i:=1 to (kol+koln) div 2 do

begin

s1:=s1+num mod 10;

num:=num div 10;

end;

for i:=1 to (kol+koln) div 2 do

begin

s2:=s2+num mod 10;

num:=num div 10;

end;

if s1=s2 then prov:=true;

end;

procedure init;

var i:integer;

begin

assign(input,'input.txt');

reset(input);

readln(s); считываем число как строку

koln:=0;i:=1;

while s[i]='0' do inc(i); считаем количество нулей

koln:=i-1;

val(s,n,cod); то что осталось переводим в число

close(input);

end;

procedure solve;

var t:longint;

begin

t:=n; делаем копию числа

kol:=0; считаем количество цифр в числе

while t>0 do

begin

inc(kol);

t:=t div 10;

end;

i:=n; проверяем числа на “счастливость”,

начиная с n

repeat

log:=prov(i);

inc(i);

until log;

res:=i-n-1; вычисляем их количество

end;

procedure out;

begin

assign(output,'output.txt');

rewrite(output);

write(res);

close(output);

end;

begin init; solve; print; end.

задачи

Задача 39 Таинственный предмет

Археологи, проводя раскопки в Египте, натолкнулись на очень странный предмет. Выглядел он, как небольшая коробочка, на которой в ряд были нанесены таинственные знаки. Каждый день символы на коробочке менялись местами. Ученых заинтересовал этот предмет, и они провели некоторые исследования. Они заметили, что знаки все время меняются по одному и тому же закону, т.е. символ, который стоит на i-ой позиции, каждый раз будет становиться на одно и то же место. Для дальнейшего исследования ученые пронумеровали символы числами от 1 до N, где N - кол-во символов, и получили информацию, как меняются знаки. Ваша задача определить через сколько дней знаки возвращаются в начальное положение.

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

Первая строка входного Input.txt файла содержит единственное число N - количество знаков (1<=N<=10000).

Далее A1 A2 ... An – закон, по которому меняются символы. (Например, запись 3 1 2 означает, что на место 1-го символа стал 3-й, на место 2-го - 1-й, на место 3-го - 2-ой.)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]