Помощь - Поиск - Пользователи - Календарь
Полная версия: Числа Смита
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Sith
Есть такая задача:
Цитата
Составное число называется числом Смита, если сумма его цифр равна сумме цифр всех чисел, образующихся разложением исходного числа на простые множители. Найти число Смита с номером N

В FAQ лежит задача, но там на Супер числа Смита. Помогите, плз, реализовать эту задачу на Паскале, т.к. с Паскалем пока только начал разбираться, а задачу уже сдавать надо sad.gif
volvo
Цитата
В FAQ лежит задача, но там на Супер числа Смита.
Не только... Просто числа Смита там тоже ищутся, см.
function GetSmith(n: Integer): LongInt;
Гость
Т.е. вот эта часть:
{
Функция для подсчета суммы цифр числа N
}
function GetOneDigits(n: LongInt): Integer;
var s: Integer;
begin
s := 0;
while n <> 0 do begin
Inc(s, n mod 10);
n := n div 10;
end;
GetOneDigits := s
end;

{
Эта функция считает сумму цифр разложения исходного числа N
на простые множители и возвращает в Amount число простых множителей
}
function GetSimpleDigits(n: LongInt; var amount: Integer): Integer;
var
s, factor: Integer;
begin
s := 0; factor := 2;
amount := 0;
repeat
if n mod factor = 0 then begin
s := s + GetOneDigits(factor); Inc(amount);
n := n div factor
end
else Inc(factor)
until n = 1;
GetSimpleDigits := s
end;

{
Функция возвращает N-ное число Смита
}
function GetSmith(n: Integer): LongInt;
var
i, amount: Integer; od, sd: Integer;
count: LongInt;
Found: Boolean;
begin
i := 0; count := 2;
while i <> n do begin
repeat
Inc(count);
Found :=
(GetOneDigits(count) = GetSimpleDigits(count, amount))
and
(amount > 1)
until Found;
Inc(i)
end;
GetSmith := Count
end;

{
Функция проверяет, является ли N числом Смита
}
function IsSmith(n: LongInt): Boolean;
var
i: Integer;
next: LongInt;
begin
i := 0;
repeat
Inc(i); next := GetSmith(i)
until next >= n;
IsSmith := (next = n)
end;


А как тогда сделать, чтобы находилось число с номером N, как просят в условии задачи?
volvo
Ну, наверное
n := ... { <-- это номер числа Смита, который будем искать }
Writeln(GetSmith(n));
Гость
А по-проще решения нет?( Мне ее уже завтра сдавать, а я не понимаю половину кода sad.gif(
volvo
Ну, сделай попроще - будет...

Что именно непонятно?
Гость
Ну например как нас учили писать проги на Паскале, это сначала прописываешь в var все переменные, потом уже сам код проги. А тут варов несколько. Плюс, как сделать чтобы он по запросу N числа (номера) выдавал соответствующее число Смита?
volvo
По многочисленным просьбам телезрителей... Брррр.... автора темы публикую реализацию данной задачи без подпрограмм:


var
n: integer;
i, candidate, buffer, T: integer;
s, s_digits, amount, factor: integer;
begin
{ Вводим номер искомого числа Смита }
write('n = '); readln(n);

{
В переменной Candidate будет храниться проверяемое на данный момент число,
в конечном итоге она будет содержать N-ое число Смита
}
candidate := 2;

{ Проходим в цикле, чтобы пропустить N-1 первых, не нужных нам, чисел Смита }
for i := 0 to n - 1 do begin
repeat

inc(candidate);

{
1 этап: найдем сумму цифр числа Candidate... Для того, чтобы не повредить
само число, будем работать с его копией - Buffer.

Алгоритм поиска суммы цифр не должен вызывать сложностей: выделение последней
цифры посредством "mod 10", суммирование этих последних цифр и удаление уже
просуммированной цифры из числа через "div 10"
}
buffer := candidate;

s_digits := 0;
while buffer <> 0 do begin
s_digits := s_digits + (buffer mod 10);
buffer := buffer div 10;
end;

{
Теперь найдем количество (amount) и сумму цифр (s) всех простых множителей
числа Candidate. Опять предотвращаем порчу числа работой с копией ...
}
buffer := candidate;

amount := 0; s := 0;
factor := 2; { Factor - это делитель ... }
repeat
if buffer mod factor = 0 then begin
{
Если остаток от деления числа на фактор = 0, значит Factor - простой множитель числа,
все что остается - найти его сумму цифр (по алгоритму, описанному выше), увеличить счетчик
простых множителей, и разделить число-кандидат на Factor, чтобы дальше продолжать
раскладывать на простые сомножители
}
T := factor;
while T <> 0 do begin

s := s + (T mod 10);
T := T div 10;

end;
amount := amount + 1;
buffer := buffer div factor;
end
else factor := factor + 1; { <--- Если же число на Factor нацело не делится - увеличиваем делитель}

{
Условие окончания цикла разложения на множители - если после очередного шага у нас
осталась единица. Все, цикл окончен, сумму цифр и количество сомножителей нашли...
}
until buffer = 1;

{
Если проверенное нами выше число - кандидат все-таки НЕ является числом Смита
(то есть, условие, записанное ниже НЕ выполняется), то внешний цикл Repeat/Until
начнется сначала, так будет продолжаться до тех пор, пока ВОТ В ЭТОМ МЕСТЕ
Candidate не будет являться числом Смита.
}
until (s_digits = s) and (amount > 1);

{
Сюда попадаем только в случае, когда предыдущее условие истинно, следовательно i-ое
число Смита мы нашли, ищем следующее или выходим (если найдено уже столько, сколько
было нужно)
}
end;

writeln(candidate); { <--- Что и требовалось найти... }
end.



Soontir Fel, задавай вопросы на форуме, а не в привате, договорились?
Soontir Fel
Спасибо!!! Просто огромнейшее спасибо за прогу и комментарии, с ними гораздо понятнее что и как!!! Стараюсь быстрее постигать паскаль, чтобы подобного больше не повторялось, и комменты очень помогают!
Ещё раз спасибо!
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.