Числа Смита (Не проходит все тесты) - Free Pascal

Узнай цену своей работы

Формулировка задачи:

Число Смита — такое составное число, сумма цифр которого равняется сумме цифр всех его простых сомножителей. Так, примером числа Смита может служить 202, поскольку 2 + 0 + 2 = 4 и 2 + 1 + 0 + 1 = 4 (202 = 2 * 101). Напишите программу, которая для заданной последовательности чисел определяет, какие из них являются числами Смита. На входе не более 20 натуральных чисел в пределах от 4 до 106. Нужно вывести строку из 0 и 1 (1, если соответствующее число является числом Смита и 0 иначе). Написал вот такую более менее понятную программку
const K=1000000;
var d:longint; p:array [2..K] of boolean;//Массив для простых чисел
 
function SumOfDigits(n:longint):longint;//Функция вычисления суммы цифр числа
var sum:longint;
begin
  sum:=0;
  while n<>0 do
  begin
     sum:=sum+(n mod 10);
     n:= n div 10;
  end;
  SumOfDigits:=sum;
end;
 
procedure FillPrime;//Процедура заполнения массива простых чисел
var i,j:longint;
begin
   for i:=2 to trunc(sqrt(K)) do
   begin
     j:=i*i;
     while (j<=K) do
     begin
       p[j]:=True;//True если число не простое
       inc(j,i);
     end;
   end;
end;
 
function SumOfPrimeDigits(n:longint):longint;//Сумма цифр всех простых делителей
var j:longint; sum:longint;
begin
  sum:=0;
  j:=2;
  while (j<=K) do
  begin
    if p[j]=True then///Если число не простое то пропустить итерацию
    begin
      inc(j);
      continue;
    end;
    if n mod j=0 then///Если простое и является делителем
    begin
      sum:=sum+SumOfDigits(j);//Тут думаю понятно
      n:=n div j;
    end else inc(j);
    if n=1 then break;
  end;
  SumOfPrimeDigits:=sum;
end;
 
begin
  FillPrime;
  while not eof do
  begin
    read(d);
    if (p[d]) and (SumOfDigits(d)=SumOfPrimeDigits(d)) then write(1) else write(0); ///Если число составное и ...
  end;
end.
Пример проходит: 4 20 17 202 1001 Не понимаю где может быть ошибка
Если так будет проще, напишите свой код. Попробую найти у себя ошибку.

Решение задачи: «Числа Смита (Не проходит все тесты)»

textual
Листинг программы
function SumCif(a:longint):byte;
var s,k:longint;
begin
k:=a;
s:=0;
while k>0 do
 begin
  s:=s+k mod 10;
  k:=k div 10;
 end;
SumCif:=s;
end;
function Smit(k:longint):boolean;
var n,a:longint;
    b:boolean;
    s:byte;
begin
a:=k;
n:=2;
s:=0;
b:=false;
while (n<=trunc(sqrt(a)))and not b do
if a mod n=0 then b:=true
else inc(n);
if b then
 begin
  a:=k;
  n:=2;
  while n<=a do
   begin
    while a mod n=0 do
     begin
      s:=s+SumCif(n);
      a:=a div n;
     end;
    inc(n);
   end;
 end;
Smit:=(SumCif(k)=s) and b;
end;
 
var i:Longint;
begin
while not seekeof do
 begin
  read(i);
  if Smit(i) then write(1)else write(0);
 end;
end.

Объяснение кода листинга программы

  1. Функция SumCif принимает целое число (a) и возвращает сумму его цифр, представленную в виде байта.
  2. Переменные k и s инициализируются значением a.
  3. Цикл while выполняет перебор цифр числа a (начиная с самой старшей), добавляя их к переменной s.
  4. Функция Smit принимает целое число (k) и возвращает true, если число является числом Смита, и false в противном случае.
  5. Переменные a, n и s инициализируются значением k.
  6. Переменная b инициализируется значением false.
  7. Цикл while выполняет перебор чисел от 2 до корня из числа a (с округлением вниз), проверяя, делится ли число a на это число без остатка.
  8. Если число a делится без остатка на текущее значение переменной n, то значение переменной b становится true.
  9. Если значение переменной b становится true, то выполняется цикл while, который перебирает все числа от 2 до значения переменной a, проверяя, делится ли число a на это число без остатка.
  10. Если число a делится без остатка на текущее значение переменной n, то значение переменной s увеличивается на значение функции SumCif, которая вызывается с текущим значением переменной n.
  11. Значение переменной a уменьшается на значение n (поскольку число a было разделено на n без остатка).
  12. Значение переменной n увеличивается на единицу.
  13. После выхода из цикла while значение переменной s содержит сумму цифр числа a.
  14. Значение переменной b становится true, если значение переменной s равно значению функции SumCif, переданной значение переменной k, и false в противном случае.
  15. В основной части программы выполняется цикл while, который считывает числа до тех пор, пока не достигнет конца файла.
  16. Каждое считанное число проверяется с помощью функции Smit.
  17. Если число является числом Смита, то на выход записывается единица, в противном случае - ноль.
  18. Цикл while продолжается до тех пор, пока не будет достигнут конец файла.

Оцени полезность:

7   голосов , оценка 4.429 из 5
Похожие ответы