Как найти наименьшее общее кратное на паскале

Вариант 1

var a,b:longint;
 
function NOD(x,y:longint):longint; { функция поиска наиб. общ. делителя }
begin
   if x<>0 then NOD:=NOD(y mod x,x) else NOD:=y;
end;
 
function NOK(x,y:longint):longint; { функция поиска наим. общ. кратного }
begin
   NOK:=( x div NOD(x,y) ) * y;
end;
 
begin { основная программа }
    readln(a,b);
    writeln( 'НОД этих чисел = ', NOD(a,b) );
    writeln( 'НОК этих чисел = ', NOK(a,b) );
end.

Вариант 2 Переборный алгоритм

var a, b, d: integer;
begin 
    write('Введите два числа: ');
    readln(a, b);
    if a < b then d := a + 1 else d := b + 1;
    {так как мы используем цикл с постусловием, необходимо минимальное значение увеличить на один, 
    иначе цикл repeat, в силу своих конструктивных 
    особенностей, не учтет это минимальное число и 
    не сделает его кандидатом в НОД. Например, 5 и 25.}
    repeat d := d - 1 
    until (a mod d = 0) and (b mod d = 0); 
write('NOD = ', d) 
end.

Вариант 3

var
m,n,r:integer;
label lb;
begin
write('Введите первое число:');readln(m);
write('Введите второе число:');readln(n);
lb:r:=m mod n;
if r=0 then writeln('НОД = ',n)
else
 begin
  m:=n;
  n:=r;
  goto lb;
 end;
end.

Вариант 4 Алгоритм Евклида с вычитанием

Пусть a и b — целые числа, тогда верны следующие утверждения:

Все общие делители пары a и b являются также общими делителями пары a — b, b;

И наоборот, все общие делители пары a — b и b являются также общими делителями пары a и b; НОД(A,  B) = НОД(A — B, B), если A > B; НОД(A, 0) = A.

Доказательство:

Если t — произвольный общий делитель a и b, то он делит и разность a — b. Действительно, из a = t * u и b = t * v следует, что a — b = t * u — t * v = t * (u — v). То есть t — также общий делитель а — b и b. Обратно, если t — произвольный делитель общий делитель a — b и b, то он делит и их сумму a — b + b = a. Это можно доказать аналогично предыдущему. Поэтому t — также общий делитель a и b. Делаем вывод, что множество общих делителей a и b совпадает с множеством делителей a — b и b. В частности, совпадают и наибольшие общие делители этих пар. Наибольшее целое, на которое делится число a, есть само число а. Число 0 делится на любое число. Отсюда наибольший общий делитель а и 0 равен а. Доказанная формула(3) позволяет свести вычисление наибольшего делителя одной пары к вычислению наибольшего общего делителя другой пары, в которой числа уже меньше. Очевидная же формула (4) дает нам понять, когда надо остановиться.

var a, b: integer;
begin 
    write('a = ');
    readln(a);
    write('b = ');
    readln(b);
    while a <> b 
        do if a > b then a := a - b else b := b - a;
    writeln('NOD = ', a);
end.

Вариант 5 Алгоритм Евклида с делением

Пусть a и b — целые числа, а r — остаток от деления a на b. Тогда НОД(a, b) = НОД(b, r). Эта формула также позволяет свести вычисление наибольшего общего делителя одной пары чисел к вычислению наибольшего обшего делителя другой пары чисел.

var a, b: integer;
begin
    write('a = ');
    readln(a);
    write('b = ');
    readln(b);
    while (a <> 0) and (b <> 0) 
        do if a >= b then a := a mod b else b := b mod a;
    write(a + b)
end.

Вариант № 6

Program test2(input,output);
Const N = 5;
Var
       С: array[1..5] of integer;
       A,B:integer;
function HOК (A, В:integer):integer;
begin
        HOK:=A*B/ HOD(A,B);
end;
function НОD(А, В:integer):integer;
var
      X,Y:integer;
begin
X:= A; Y: = В;
1:IF X = Y THEN HOD:=X;
IF X > Y THEN begin
                           X:= X – Y;goto 1;
                           end;
IF Y > X THEN begin
                           Y:= Y – X;goto 1;
                           end;
end;
Begin
FOR i= 1 ТО N READ (C[i]);
A:= С ([l])
FOR i = 1 TO N–1 begin B:=С[i + 1];
                                          A:= HOK(A,B);
                               end;
writeln ("HOK="; A);
end.

Вариант 7

Program N_O_D (Input, Output); 
Var 
A, B: LongInt; 
NOD : LongInt; 
 
Begin
 
WriteLn ('PASCAL: Нахождение Н.О.Д. двух заданных чисел.');
Writeln ('Введите числа, для которых ищется НОД:'); 
Write('Первое число: ');ReadLn (A);
Write('Второе число: ');ReadLn (B); 
 
If (A < B)ThenNOD := A Else NOD := B;
 
While Not( (A mod NOD = 0) and (B mod NOD = 0) ) do 
NOD := NOD - 1;
 
WriteLn ('НОД = ',NOD);
 
ReadLn;
End. 

Program N_O_D (Input, Output); 
Var 
A, B: LongInt; 
NOK, NOD : LongInt; 
 
Begin
 
WriteLn ('PASCAL: Нахождение Н.О.К. двух заданных чисел.');
WriteLn ('Введите числа, для которых ищется НОК:'); 
Write ('Первое число: ');ReadLn (A); 
Write ('Второе число: ');ReadLn (B);
 
If (A < B)ThenNOD := A Else NOD := B;
 
While Not ( (A Mod NOD = 0) And (B Mod NOD = 0) ) Do 
NOD := NOD - 1;
 
A := A Div NOD;
B := B Div NOD; 
NOK := A * B * NOD; 
WriteLn ('НОК = ', NOK); 
 
ReadLn;
End. 

0 / 0 / 0

Регистрация: 07.05.2010

Сообщений: 43

1

Найти НОК

27.05.2010, 08:38. Показов 18794. Ответов 2


Студворк — интернет-сервис помощи студентам

Найти НОК(а,с). (НОК(а,с)=а*с/НОД(а,с)).



0



MURO4K@

27.05.2010, 16:07

3

Лучший ответ Сообщение было отмечено Aquamarine как решение

Решение

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
Var
  a,b,c:integer;
  nok:real;
Begin
  readln(a,b);
  c:=a*b;
  while a<>b do
   if a>b then a:=a-b
            else b:=b-a;
  nok:=c/a;
  writeln(nok);
End.

IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

27.05.2010, 16:07

Помогаю со студенческими работами здесь

НОД И НОК
Как решить..

НОД и НОК
Народ, помогите! Надо написать программу:
Даны два числа а и b. Найти НОД и НОК.

НОК и факторизация
Собственно говоря, программы есть, вот только я не знаю, как можно сократить время их работы….

НОК алгоритм Евклида
Определить НОК (наименьшее общее кратное) двух чисел, используя алгоритм Евклида для вычисления НОД…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

3

Паскаль - Урок 21: Основные алгоритмы Паскаль (Часть 1)

При программировании на любом языке необходимо знать основные алгоритмы. Они являются как бы «азбукой» для программиста. Сегодня я хочу рассказать про основные алгоритмы в таком языке программирования, как Паскаль.

1. Первый алгоритм, про который я расскажу — это факториал натурального числа Pascal. Факториалом числа (!n) является произведение натуральных чисел от 1 до этого числа включительно. Например, 5!=1*2*3*4*5.

Наша задача — написать программу Pascal, которая находит факториал числа.

Сначала переменной f (сокр. Factorial) присваиваем значение, равное единице, т.к 0! = 1, 1!=1.
Далее идет цикл с параметром от 2 до заданного числа, в котором переменная f умножается на следующее значение после единицы с увеличением на 1 после каждого круга.

Программа нахождения факториала на языке Паскаль:

var
    f: longint;
    n, i: integer;
Begin
    write('n = '); readln(n);
    f := 1;
    For i:=2 to n do
        f := f * i;
    writeln(n,'! = ', f);
End.

2. Второй алгоритм, который необходимо знать — нахождение НОК двух чисел. НОК — наименьшее общее кратное, то есть минимальное число, которое одновременно делится на оба числа.

В паскаль это реализуется достаточно просто:

var a,b,c:integer; //Описание переменных
begin //Начало программы
	readln(a,b); //Считывание а и б
	c:=a*b; //Перемножение
	repeat //Цикл с постусловием
		if a>b then a:=a-b else b:=b-a;   
	until a=b; //Цикл до тех пор, пока а не равно б
	c:= c div a; //Делим c на a нацело и получаем нок
	writeln('НОК=', c); //Выводим значение
end.//Конец программы

Скачать: nok.pas

3. Также нужно знать и про НОД двух чисел. НОД — наименьший общий делитель, т. е. Минимальное число, которое нацело делит два и более чисел.

Код нахождения НОД в паскаль:

var a,b,c: integer; //Описание переменных
begin //Начало программы
  writeln('Введите a,b: '); //Диалог с пользователем
  read(a,b);  //Чистывание чисел
  while b<>0 do //Вход в цикл while, пока b не равно 0
  begin
    c := a mod b; //Присваивание с остатка деления a/b
    a := b; 
    b := c;
  end;
  writeln('НОД = ',a); //Вывод делителя
end.//Конец программы 

Скачать: nod.pas
На сегодня все, во второй части расскажу про возведение числа в степень, а также про нахождение минимального и максимального в массиве.

Дата: 2013-10-04 13:18:03   Просмотров: 45349

Теги: Паскаль урок уроки Pascal основные алгоритмы

Содержание

Математика и числа

Чётность/нечётность чисел

if Odd (Number) then 
  writeln (Number, ' нечётно')
else
  writeln (Number, ' чётно');

Делимость (кратность) чисел

if Number mod 3 = 0 then
  writeln (Number, ' делится на 3 без остатка');

Делиться без остатка – означает кратность.

Наибольший Общий Делитель

(НОД, англ. Greatest Common Divisor)

{ Евклид (Euclidus) }
function GCD (A: integer;  B: integer): integer;
begin
    while (a <> 0) and (b <> 0) do
       if a >= b then
         a := a mod b
       else 
         b := b mod a;
    GCD := a + b; { один - ноль }
end;

Наименьшее Общее Кратное

(НОК, англ. Least Common Multiplier)

function LCM (A: integer;  B: integer): integer; 
begin
     LCM := a * b div GCD (a, b)
end;

Степень

Для целых чисел

function Power(Base, N: integer): longint;
{ Base - основание , N - степень }
var
   Result: longint;
   i: word;
begin
   Result := 1; { придаём начальное значение }
   for i := 1 to N do
     Result := Result * Base;
 
   Power := Result;
end;

Для вещественных чисел

Возвести A в степень N. Ограничения: [COLOR=red]только для A > 0[/COLOR]

function PowerExp (A, N: real): real;
begin
   if A > 0 then
     PowerExp := Exp ( N * Ln (A) )
   else 
     PowerExp := 0;
end;

Факториал

function Factorial(N: word): longint;
var
   Result: longint;
   i: word;
begin
   Result := 1;
   for i := 1 to N do 
     Result := Result * N;
 
   Power := Result;
end;

С использованием рекурсии

function Factorial (N: word): longint;
begin
   if N = 0 then
     Factorial := 1 
   else 
     Factorial := N * Factorial (N - 1);
end;

Вещественный и целый типы

Round – Округляет значение вещественного типа до значения целого типа, округляя.
Trunc – Округляет значение вещественного типа до значения целого типа, отбрасывая дробную часть.
Frac – Возвращает дробную часть аргумента.
Int – Возвращает целую часть аргумента.

   var
       r : real;
     begin
       r := Round ( 123.456);  {    123 }
       r := Round ( 123.778);  {    124 }
       r := Trunc ( 123.456);  {    123 }
       r := Trunc (-123.778);  {   -123 }
       r := Frac  ( 123.456);  {  0.456 }
       r := Int   ( 123.456);  {  123.0 }
       r := Int   (-123.456);  { -123.0 }
     end.

Случайные числа

Процедура Randomize – инициализирует генератор чисел.
Функция Random (N) выдает целочисленные значения в диапазоне от 0 до N-1 !
Например, чтобы сгенерировать число X в диапазоне -N..N , пишем так:

  Randomize;
  X := Random (N + 1) - 2 * N;

Если не написать сначала Randomize; , то будут генерироваться одни и те же числа.

Как проверить простое ли число?

function isPrime(X: word): boolean;
var
i: integer;
Begin
     isPrime:=false;
     if not odd(x) and (x<>2) { проверяем на чётность  }
          then exit;
     i:=3;
     while i <= sqrt(x) do { проверяем только нечётные }
     begin
          if x mod i = 0 then Exit;
          inc(i,2);
     end;
 
     isPrime:=true;
End;

Разложение числа на множители

procedure Factorization(x: word);
var i: word;
 
 procedure DivX; { делим на простое число, пока делится без остатка }
 begin
      while (x>1) and (x mod i = 0) do
      begin
           write(i:4);
           x:= x div i;
      end;
 end;
 
begin
     i:=2;
     DivX;
     i:=3;
     while (i < x div 2) do
     begin
           DivX;
           inc(i,2); { <=> i:=i+2; только нечётные числа }
     end;
     if x>1 then writeln(x:4);
end;

Приближённое представление числа в виде дроби

VAR p,q,qmax:integer;
    d, r, min: real;
BEGIN
   write('r, qmax=');
   readln(r, qmax); { r - не целое число, qmax - кол-во итераций (циклов) }
   p:=0; q:=1; min:=r;
   REPEAT
     IF p / q < r
          THEN inc(p)
          ELSE inc(q);
     d:=abs(r-p/q);
     IF d < min THEN
     BEGIN
          min:=d;
          writeln(p:7,'/',q)
     END
   UNTIL (q >= qmax) OR (d = 0);
   readln;
END.

Как работать с отдельными битами?

FUNCTION IsBitOn (n: word; b : BYTE): BOOLEAN; { Проверяем, установлен ли бит }
BEGIN 
     isBitOn:=((n SHR b) AND 1) = 1
END;
 
PROCEDURE SetBitOn (VAR n: Word; b: BYTE); { Устанавливаем бит }
BEGIN
     N:= N OR (1 SHL b)
END;
 
PROCEDURE XORBit (VAR n: Word; b: BYTE); { Переключаем бит }
BEGIN
     N:= N XOR (1 SHL b)
END;

Как узнать из каких цифр состоит целое число?

Var X : Integer;
Begin
 X:=12345;
 Writeln('Число состоит из таких цифр:');
 While X <> 0 Do
  Begin
   Writeln(X Mod 10);
   X:=X Div 10;
  End;
End.

Как быстро делить/умножать числа на степень двойки ?

Как известно, опрерации умножения и деления занимаю много машинного времени. Если требуется скорость, то целесообразно использовать логические сдвиги:

i:=i shl 1; { i:=i * 2^1}
i:=i shl 2; { i:=i * 2^2}
{и т.д.}
i:=i shr 1; { i:=i div 2^1}
i:=i shr 2; { i:=i div 2^2}
{и т.д.}

Примечание: корректно работает только с целыми беззнаковыми типами (word, byte…)!
Если производить эти операции со знаковыми типами, то бит знака тоже сдвигается и в результате
число может поменять свой знак!

Более быстрое разложение числа на множители

В методе, описанном ранее, количество проверок пропорционально sqrt(N), т.е. для разложение числа порядка 1012 потребуется около 106 операций, причем используется деление!
Существуют методы поиска делителей, которые справляются со своей задачей намного быстрее (без операций деления).
В методе Ферма предполагается, что N – нечетное число, причем N = uv. Попробуем подобрать такие числа X и Y, что будет выполняться:
N = p2 – q2. Обозначим u = (p + q) / 2 и v = (p – q) / 2.
Будем пытаться приблизить числа p и q с разных сторон, чтобы выполнялось N = p2 – q2.
Итак, сам алгоритм:

  • Присвоим x = 2 * trunc(sqrt(N)) + 1, y = 1, r = sqr(trunc(sqrt(N))) – N (во время выполнения алгоритма числа x, y и r будут соответствовать 2p + 1, 2q + 1 и p2 – q2 – N)

  • Если r = 0, то выполнение алгоритма заканчивается. Имеем N = ((x-y)/2)((x+y-2)/2) и (x-y)/2 – наибольши делитель числа N.

  • Присвоить r = r + x, x = x + 2 (шаг по x)

  • Присовить r = r – y, y = y – 2 (шаг по y). Делать этот шаг, пока r > 0.

  • Перейти к проверке r = 0

Так как все действия алгоритма – это сложения и вычитания, то они на компьютере выполняются очень быстро. В результате работы алгоритма будет получено одно число – наибольший делитель числа N. Замечание: данный алгоритм лучше использовать для поиска больших делителей, нежели для маленьких!

{$N+, E+}
 
function FermaFactorization (N : Comp) : Comp;
 
var
  X, Y, R, Z, ZZ : Comp;
 
begin
 Z := Sqrt(N);
 ZZ := Trunc (Z);
 X := 2 * ZZ + 1;
 Y := 1;
 R := Sqr (ZZ) - N;
 while (R <> 0) do
  begin
   R := R + X;
   X := X + 2;
   repeat
    R := R - Y;
    Y := Y + 2;
   until R <= 0;
  end;
 FermaFactorization := (X - Y) / 2;
end;
 
begin
 Writeln (FermaFactorization(917979909) : 0 : 0);
end.

Перейти к содержимому

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

Примечание: наименьшим общим кратным двух чисел m и n называется наименьшее натуральное число, которое делится на m и n. Обозначение: НОК(m, n)

Решение. Из теории чисел известно, что НОК(m, n) связан с НОД(m, n) следующим образом:

Следовательно, для нахождения ответа нам нужно лишь использовать предыдущую задачу нахождения НОД двух чисел m иn:

while m <> n do begin

if m > n then begin

m := m — n

end

else begin

n := n — m

end

end;

Так как исходные переменные будут испорчены в процессе работы алгоритма Евклида, нам нужно вычислить их произведение до входа в описанный выше цикл и присвоить это произведение переменной prod (от англ. product – «произведение»):

prod := m * n;

После этого нам остается вывести на экран результат арифметического выражения в правой части нашей формулы. В качестве самого НОД будет использоваться переменная m:

writeln(prod div m);

Кстати, деление в формуле будет целочисленным (через div) именно потому, что если два числа делятся на некоторое число, то и их произведение также делится на него.

Код:

  1. program LeastCommonMult;
  2. var
  3. m, n, prod: word;
  4. begin
  5. readln(m, n);
  6. prod := m * n;
  7. while m <> n do begin
  8. if m > n then begin
  9. m := m — n
  10. end
  11. else begin
  12. n := n — m
  13. end
  14. end;
  15. writeln(prod div m)
  16. end.

Добавить комментарий