Составное число называется числом Смита, если сумма его цифр равна сумме цифр всех чисел, образующихся разложением исходного числа на простые множители. Найти число Смита с номером N
В FAQ лежит задача, но там на Супер числа Смита. Помогите, плз, реализовать эту задачу на Паскале, т.к. с Паскалем пока только начал разбираться, а задачу уже сдавать надо
volvo
15.10.2007 0:19
Цитата
В FAQ лежит задача, но там на Супер числа Смита.
Не только... Просто числа Смита там тоже ищутся, см.
function GetSmith(n: Integer): LongInt;
Гость
15.10.2007 1:52
Т.е. вот эта часть:
{ Функция для подсчета суммы цифр числа 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
15.10.2007 1:57
Ну, наверное
n := ... { <-- это номер числа Смита, который будем искать } Writeln(GetSmith(n));
Гость
15.10.2007 20:01
А по-проще решения нет?( Мне ее уже завтра сдавать, а я не понимаю половину кода (
volvo
15.10.2007 20:06
Ну, сделай попроще - будет...
Что именно непонятно?
Гость
21.10.2007 20:56
Ну например как нас учили писать проги на Паскале, это сначала прописываешь в var все переменные, потом уже сам код проги. А тут варов несколько. Плюс, как сделать чтобы он по запросу N числа (номера) выдавал соответствующее число Смита?
volvo
24.10.2007 23:23
По многочисленным просьбам телезрителей... Брррр.... автора темы публикую реализацию данной задачи без подпрограмм:
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
25.10.2007 2:11
Спасибо!!! Просто огромнейшее спасибо за прогу и комментарии, с ними гораздо понятнее что и как!!! Стараюсь быстрее постигать паскаль, чтобы подобного больше не повторялось, и комменты очень помогают! Ещё раз спасибо!
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.