<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=330611&amp;view=findpost&amp;p=2776843</guid>
        <pubDate>Sun, 12 Dec 2010 20:04:55 +0000</pubDate>
        <title>Замечательные числа</title>
        <link>https://forum.sources.ru/index.php?showtopic=330611&amp;view=findpost&amp;p=2776843</link>
        <description><![CDATA[volvo877: <span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>Числа и СуперЧисла Смита</strong></span><br>
<br>
Составное число называется Числом Смита, если сумма его цифр равна сумме цифр всех чисел, образующихся разложением исходного числа на простые множители. Число Смита называется СуперЧислом Смита, если сумма его цифр является Числом Смита.<br>
<br>
Приведенные ниже программы ищут СуперЧисло Смита с номером X...<br>
<br>
<div class="tag-spoiler spoiler closed"><div class="spoiler_header" onclick="openCloseParent(this)">Для начала - программа, показывающая, как делать не надо</div><div class="body"><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{ Эта функция считает сумму цифр числа N }</div><div class="code_line">function GetOneDigits (n : LongInt) : integer;</div><div class="code_line">var s : Integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; s := 0;</div><div class="code_line">&nbsp;&nbsp; while n &#60;&#62; 0 do begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Inc(s, n mod 10);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;n := n div 10</div><div class="code_line">&nbsp;&nbsp; end;</div><div class="code_line">&nbsp;&nbsp; GetOneDigits := s</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; Эта функция считает сумму цифр разложения исходного числа N</div><div class="code_line">&nbsp;&nbsp; на простые множители и возвращает в Amount число простых множителей</div><div class="code_line">}</div><div class="code_line">function GetSimpleDigits (n : LongInt; Var amount : Integer) : Integer;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; s, factor : Integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; s := 0; factor := 2;</div><div class="code_line">&nbsp;&nbsp; amount := 0;</div><div class="code_line">&nbsp;&nbsp; repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if n mod factor = 0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; s := s + GetOneDigits (factor); Inc (amount);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; n := n div factor</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else Inc (factor)</div><div class="code_line">&nbsp;&nbsp; until n = 1;</div><div class="code_line">&nbsp;&nbsp; GetSimpleDigits := s</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ Функция возвращает N-ное число Смита }</div><div class="code_line">function GetSmith (n : Integer) : LongInt;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; i, amount : Integer; od, sd : Integer;</div><div class="code_line">&nbsp;&nbsp; count : LongInt;</div><div class="code_line">&nbsp;&nbsp; Found : Boolean;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; i := 0; count := 2;</div><div class="code_line">&nbsp;&nbsp; while i &#60;&#62; n do</div><div class="code_line">&nbsp;&nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; Inc(count);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; Found :=</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(GetOneDigits (count) = GetSimpleDigits (count, amount)) and</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(amount &#62; 1)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;until Found;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;inc(i)</div><div class="code_line">&nbsp;&nbsp; end;</div><div class="code_line">&nbsp;&nbsp; GetSmith := Count</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ Функция проверяет, является ли N числом Смита }</div><div class="code_line">function IsSmith (n : LongInt) : Boolean;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; i : Integer;</div><div class="code_line">&nbsp;&nbsp; next : LongInt;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; i := 0;</div><div class="code_line">&nbsp;&nbsp; repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Inc(i); next := GetSmith (i)</div><div class="code_line">&nbsp;&nbsp; until next &#62;= n;</div><div class="code_line">&nbsp;&nbsp; IsSmith := (next = n)</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ Функция возвращает N-ное суперчисло Смита }</div><div class="code_line">function Super (n : Integer) : LongInt;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; i, count : Integer;</div><div class="code_line">&nbsp;&nbsp; smith : LongInt;</div><div class="code_line">&nbsp;&nbsp; Found : Boolean;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; i := 0; count := 0;</div><div class="code_line">&nbsp;&nbsp; while i &#60;&#62; n do</div><div class="code_line">&nbsp;&nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Inc(i);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; Inc (count);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; smith := GetSmith (count);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; Found := IsSmith (GetOneDigits (smith));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;until Found;</div><div class="code_line">&nbsp;&nbsp; end;</div><div class="code_line">&nbsp;&nbsp; Super := smith</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; X : Integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Write (&#39;X = &#39;); ReadLn (X);</div><div class="code_line">&nbsp;&nbsp;WriteLn (&#39;Smith super number (X) = &#39;, Super (X));</div><div class="code_line">end.</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script></div></div>Почему не надо так делать? Потому, что при вычислении последующих чисел Смита заново вычисляются все предыдущие. Что очень сильно замедляет программу.<br>
<br>
Чтобы ускорить ее, немного изменим структуру программы: при нахождении следующего числа Смита не будем пересчитывать все предыдущие, а воспользуемся сразу числом, уже найденным на предыдущей итерации...<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; Как и прежде, функция, суммирующая все цифры числа,</div><div class="code_line">&nbsp;&nbsp; переданного ей в качестве параметра</div><div class="code_line">}</div><div class="code_line">function sum_of_digits (n : longint) : integer;</div><div class="code_line">var s : integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; s := 0;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; while n &#60;&#62; 0 do</div><div class="code_line">&nbsp;&nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;inc(s, n mod 10);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;n := n div 10;</div><div class="code_line">&nbsp;&nbsp; end;</div><div class="code_line">&nbsp;&nbsp; sum_of_digits := s</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; Функция, раскладывающая переданное ей число на простые множители,</div><div class="code_line">&nbsp;&nbsp; и находящая сумму цифр всех этих множителей</div><div class="code_line">}</div><div class="code_line">function Factorization (X : longint) : longint;</div><div class="code_line">var i, s : word;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; procedure DivX;</div><div class="code_line">&nbsp;&nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;while (x &#62; 1) and (x mod i = 0) do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; inc (s, sum_of_digits (i));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; x := x div i;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; s := 0;</div><div class="code_line">&nbsp;&nbsp; i := 2;</div><div class="code_line">&nbsp;&nbsp; DivX;</div><div class="code_line">&nbsp;&nbsp; i := 3;</div><div class="code_line">&nbsp;&nbsp; while (i &#60; x div 2) do begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;DivX;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;inc(i, 2);</div><div class="code_line">&nbsp;&nbsp; end;</div><div class="code_line">&nbsp;&nbsp; if x &#62; 1 then inc(s, sum_of_digits (x));</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; Factorization := s;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; Функция, проверяющая число на простоту</div><div class="code_line">}</div><div class="code_line">function IsPrime (X : word): boolean;</div><div class="code_line">var i : integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; isPrime := false;</div><div class="code_line">&nbsp;&nbsp; if not odd(x) and (x &#60;&#62; 2) then exit;</div><div class="code_line">&nbsp;&nbsp; i := 3;</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; while i &#60;= sqrt(x) do</div><div class="code_line">&nbsp;&nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if x mod i = 0 then exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;inc (i, 2);</div><div class="code_line">&nbsp;&nbsp; end;</div><div class="code_line">&nbsp;&nbsp; IsPrime := true;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; Функция IsSmith осуществляет проверку, является ли переданное ей</div><div class="code_line">&nbsp;&nbsp; число &quot;числом Смита&quot;</div><div class="code_line">}</div><div class="code_line">function IsSmith(n: longint): boolean;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; IsSmith :=</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;not IsPrime (n) and</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;(sum_of_digits (n) = Factorization (n));</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; С помощью функции GetNextSmith, можно получить i-ое число Смита,</div><div class="code_line">&nbsp;&nbsp; зная предыдущее, (i - 1)-ое. Очень сильно ускорит программу, поскольку</div><div class="code_line">&nbsp;&nbsp; избавляет от необходимости постоянно пересчитывать одни и те же числа ...</div><div class="code_line">}</div><div class="code_line">function GetNextSmith (prev : longint) : longint;</div><div class="code_line">var i : longint;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; i := prev;</div><div class="code_line">&nbsp;&nbsp; repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;inc (i);</div><div class="code_line">&nbsp;&nbsp; until IsSmith (i);</div><div class="code_line">&nbsp;&nbsp; GetNextSmith := i;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; Нахождение Суперчисла Смита под номером N</div><div class="code_line">}</div><div class="code_line">function Super(n: integer): longint;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; i, curr : longint;</div><div class="code_line">&nbsp;&nbsp; smith : longint;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; curr := 0; i := 0;</div><div class="code_line">&nbsp;&nbsp; smith := 2;</div><div class="code_line">&nbsp;&nbsp; repeat</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; inc (i);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; smith := GetNextSmith (smith);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;until IsSmith (sum_of_digits(smith));</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;inc(curr);</div><div class="code_line">&nbsp;&nbsp; until curr = n;</div><div class="code_line">&nbsp;&nbsp; Super := smith;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; X : Integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; write (&#39;X = &#39;); readln &nbsp;(X);</div><div class="code_line">&nbsp;&nbsp; writeln(&#39;Smith super number (X) = &#39;, Super (X));</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
В результате получаем программу, работающую быстрее предыдущей версии во много раз. После замеров времени выполнения получилось следующее:<br>
СуперСмит<sub class='tag-sub'>5</sub>. Старая версия: 62 мс., новая: 1 мс.<br>
СуперСмит<sub class='tag-sub'>100</sub>. Старая версия: 7653 мс., новая: 63 мс.<br>
СуперСмит<sub class='tag-sub'>200</sub>. Старая версия: 43891 мс., новая: 220 мс.<br>
<br>
<br>
<br>
<strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Числа Армстронга</span></strong><br>
<br>
Число Армстронга - такое число из k цифр, для которого сумма k-х степеней его цифр равна самому этому числу, например 153 = 1<sup class='tag-sup'>3</sup> + 5<sup class='tag-sup'>3</sup> + 3<sup class='tag-sup'>3</sup><br>
Ниже приведены две функции для работы с числами Армстронга:<br>
<ul class="tag-list"><li><span class="tag-color tag-color-named" data-value="purple" style="color: purple">Function IsArmstrong(n: LongInt): Boolean;</span><br>
Возвращает True, если переданное ей в качестве аргумента число является числом Армстронга.</li><li><span class="tag-color tag-color-named" data-value="purple" style="color: purple">Procedure GetArmstrongs(n: integer);</span><br>
Распечатывает все n-значные числа Армстронга</li></ul><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function Power (n, k : Integer) : LongInt;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; p : LongInt; i : Word;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; p := 1;</div><div class="code_line">&nbsp;&nbsp; for i := 1 to k do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;p := p * n;</div><div class="code_line">&nbsp;&nbsp; Power := p</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function IsArmstrong (n : LongInt) : Boolean;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; Weight : Array [0 .. 9] Of LongInt;</div><div class="code_line">&nbsp;&nbsp; i, j : Integer; s : LongInt;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; i := -1; s := n;</div><div class="code_line">&nbsp;&nbsp; while s &#62; 0 do</div><div class="code_line">&nbsp;&nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Inc (i);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Weight [i] := s mod 10;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;s := s div 10</div><div class="code_line">&nbsp;&nbsp; end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; for j := 0 to i do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;s := s + Power (Weight [j], Succ (i));</div><div class="code_line">&nbsp;&nbsp; IsArmstrong := (s = n)</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure GetArmstrongs (n : integer);</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; Weight : Array [0 .. 9] Of LongInt;</div><div class="code_line">&nbsp;&nbsp; k, x, min, max, s, p : LongInt;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; for k := 0 to 9 do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Weight[k] := Power (k, n);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; min := Power (10, Pred(n));</div><div class="code_line">&nbsp;&nbsp; max := Pred (10 * min);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; for x := min to max do</div><div class="code_line">&nbsp;&nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;p := x; s := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for k := 1 to n do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; Inc (s, Weight [p mod 10]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; p := p div 10</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if s = x then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; WriteLn (x, &#39; - Armstrong&#39;)</div><div class="code_line">&nbsp;&nbsp; end</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; n : 1 .. 9;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Write (&#39;n [1 .. 9] = &#39;); ReadLn (n)</div><div class="code_line">&nbsp;&nbsp; until n In [1 .. 9];</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;GetArmstrongs (n);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;WriteLn (&#39;1741725: &#39;, isArmstrong (1741725))</div><div class="code_line">end.</div></ol></div></div></div></div><br>
<br>
<br>
<strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Совершенные числа</span></strong><br>
<br>
Сушествует особый класс чисел, равных сумме всех своих делителей, отличных от самого числа. То есть,<br>
<br>
6 = 1 + 2 + 3<br>
28 = 1 + 2 + 4 + 7 + 14<br>
<br>
и так далее...<br>
<br>
Конечно, нахождение совершенных чисел можно реализовать несколькими способами. По традиции: сначала -<br>
<div class="tag-spoiler spoiler closed"><div class="spoiler_header" onclick="openCloseParent(this)">программа, показывающая, как не надо искать Совершенные числа</div><div class="body"><div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">const</div><div class="code_line">&nbsp;&nbsp;final = 500000;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; i, s, divider : longint;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; for i := 2 to final do begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;s := 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for divider := 2 to trunc (sqrt (i)) do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; if i mod divider = 0 then s := s + divider + (i div divider);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if i = s then writeln(s);</div><div class="code_line">&nbsp;&nbsp; end;</div><div class="code_line">end.</div></ol></div></div></div></div></div></div>Эта программа выдаст все совершенные числа на промежутке [2 .. final], но она будет довольно долго работать (тем дольше, чем шире просматриваемый интервал).<br>
<br>
Между тем, количество кандидатов на роль совершенных чисел можно <strong class='tag-b'>значительно</strong> сократить, пользуясь тем фактом, что во всех Совершенных числах в двоичной записи сначала идут <strong class='tag-b'>n</strong> единиц, а потом <strong class='tag-b'>(n - 1)</strong> нулей. Это позволяет организовать поиск Совершенных чисел вот таким, например, образом:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; i, n, s : longint;</div><div class="code_line">&nbsp;&nbsp; divider : integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; bin, bs : integer; { Счетчики для работы со строками }</div><div class="code_line">&nbsp;&nbsp; bin_s : string; &nbsp; &nbsp;{ Строковое представление Совершенного числа в двоичном виде }</div><div class="code_line">&nbsp;&nbsp; check : LongInt; &nbsp; { Число - кандидат на роль Совершенного }</div><div class="code_line">begin</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; { Проверим все числа, двоичная запись которых содержит 3 .. 29 символов }</div><div class="code_line">&nbsp;&nbsp; for bin := 1 to 14 do</div><div class="code_line">&nbsp;&nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;bin_s := &#39;&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;{ Создаем бинарное представление числа-кандидата на роль Совершенного }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for bs := 1 to bin do bin_s := &#39;1&#39; + bin_s + &#39;0&#39;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;bin_s := &#39;1&#39; + bin_s;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;{ Переводим его из 2 представления в десятичное }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;check := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for i := 1 to length (bin_s) do check:= check * 2 + (ord (bin_s[i]) - ord (&#39;0&#39;));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; ... а теперь - проверяем ТОЛЬКО его, пропуская сотни тысяч чисел, проверка которых</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; заведомо не приведет к успеху (здесь еще тоже можно пооптимизировать, но результат</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; и так выдается практически мгновенно)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;s := 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for divider := 2 to trunc (sqrt (check)) do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; if check mod divider = 0 then s := s + divider + (check div divider);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if check = s then WriteLn (check);</div><div class="code_line">&nbsp;&nbsp; end;</div><div class="code_line">end.</div></ol></div></div></div></div>]]></description>
        <author>volvo877</author>
        <category>Все языки: Статьи, заготовки в FAQ</category>
      </item>
	
      </channel>
      </rss>
	