Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
Баловался этой фигней (код внутри) 16.06.03 16:07 Число просмотров: 1532
Автор: Chingachguk <Chingachguk> Статус: Member
|
Позволяет секунд за 5 на P800 сосчитать для чисел около 1000. Дальше надо либо с расширенной памятью (dpmi и тд) возиться, либо с диском ;)
Язык почти детский - tp7.
{$A-} {no align data}
{$N+} {math coprocessor and 8-bytes reals}
{$G+} {Instructions of processor 286 eanable}
{$M 60000,0,655008} {Stack=60000 bytes, Min Heap=0, MaxHeap= 655008 bytes}
type
sres = double; {Переменная, способная вместить число сумм}
const
MaxValidNumber = 1000;
MaxPTablesNum = 35; {Число P-таблиц для запоминания числа сумм}
type
Table = array[0..MaxValidNumber] of sres;
PoTable = ^Table;
var
P:array[0..MaxValidNumber] of sres;
PTable:array[1..MaxPTablesNum] of PoTable;
Simples: array [1..(MaxValidNumber shr 2)+1] of word;
function Is_SimpleNumber(Num:word):boolean;
var
i: word;
begin
Is_SimpleNumber:=false;
if ((Num=0) or (Num=1)) then exit;
if Num>3 then
begin
if (Num and 1)=0 then exit;
if (Num and 3)=0 then exit;
end;
Is_SimpleNumber:=true;
for i:=3 to (Num-1) do
if (Num mod i)=0 then
begin
Is_SimpleNumber:=false;
exit;
end;
end;
{Вычислить число разложений, используя таблицу P[] для Num-1,Num-2..}
function Sum_NumberBest(Num:integer; MaxSimple:word):sres;
var
result: sres;
i: word;
SimplesNum: word;
delta: word;
begin
Sum_NumberBest:=0;
SimplesNum:=0;
if MaxSimple>0 then SimplesNum:=MaxSimple
else
begin
i:=1;
while (Simples[i]<=Num) do
begin
if ((MaxSimple>0) and (Simples[i]>MaxSimple)) then break;
inc(SimplesNum);
inc(i);
end;
end;
result:=0;
{if Is_SimpleNumber(Num)=true then inc(result);}
{Получили число простых чисел в интервале в SimplesNum}
{Выполняем переборы коэффициентов}
for i:=SimplesNum downto 1 do
begin
{writeln('Current simple:',Simples[i]);}
{Разница между заданным числом и старшим текущим простым}
delta:=Num-Simples[i];
{+Число разложений через простые числа, не большие текущего простого}
{Используем для этого таблицу P}
if delta<=Simples[i] then result:=result+P[delta] else
begin
if Simples[i]>Simples[MaxPTablesNum+1] then
result:=result+Sum_NumberBest(delta,i)
else
begin
if Simples[i]=2 then
begin
if (delta and 1)=0 then result:=result+1;
end
else
if PTable[i-1]^[delta]>0 then result:=result+PTable[i-1]^[delta]
else result:=result+Sum_NumberBest(delta,i);
end;
end;
end;
if MaxSimple>0 then
if ((Simples[MaxSimple]<=Simples[MaxPTablesNum]) and (Simples[MaxSimple]>=3))
then PTable[MaxSimple-1]^[Num]:=result;
Sum_NumberBest:=result;
end;
var
i,j,k: word;
begin
{Выделить память под P-таблицы}
for i:=1 to MaxPTablesNum do
begin
getmem(PTable[i],sizeof(Table));
if PTable[i]=nil then
begin
writeln('Can''t allocate memory !');
readln;
exit;
end;
end;
{Запомнить все простые числа в интервале 0..MaxValidNumber
и обнулить таблицы}
j:=0;
for i:=0 to MaxValidNumber do
begin
for k:=1 to MaxPTablesNum do PTable[k]^[i]:=0;
if Is_SimpleNumber(i)=true then
begin
inc(j);
Simples[j]:=i;
writeln('Number ',Simples[j],' is simple');
end;
end;
writeln('Total: ',j);
writeln;
{Найдем следующее простое за MaxValidNumber число}
i:=MaxValidNumber;
while not Is_SimpleNumber(i)=true do inc(i);
Simples[j+1]:=i;
{Вычисляем число разложений чисел до N, запоминаем их}
P[0]:=1;
for i:=1 to 1000 do
begin
P[i]:=Sum_NumberBest(i,0);
writeln('Number of sum for ',i,' is ',P[i]:12);
end;
{Освободить память из-под P-таблиц}
for i:=1 to MaxPTablesNum do freemem(PTable[i],sizeof(Table));
end.
|
|
|