Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11642
Последний выпуск: 19.06.2015

Задачи с простыми числами.

Представлен ряд задач, связанных с простыми числами - натуральными (целыми положительными) числами, большими 1, не имеющими других делителей, кроме самих себя и единицы.

Рассмотрим сначала такую задачу:


Задача 1. <Дано натуральное число n. Проверить, является ли оно простым>.

Метод решения этой задачи очевиден. Если n - четное, то оно не простое (составное), иначе следует проверить, являются ли делителем n числа 3, 5, 7,...,n/3 (проверять до n-1 и даже до n/2 нет необходимости), и если хотя бы для одного числа ответ будет положительным, то число n - составное. Заметим при этом, что число 2 - простое.

Программа на школьном алгоритмическом языке имеет вид:

алг Проверка 
нач цел n,i, лог simp 
| вывод нс, "n=" 
| ввод n 
| если n=2 
| |то вывод нс, "Это число простое" 
| |иначе 
| | если mod(n,2) = 0                    |n - четное число 
| | |то вывод нс, "Это число составное" 
| | |иначе 
| | | simp:=да 
| | | нц для i от 3 до div(n,3) шаг 2 
| | | | если mod(n,i)=0                  |встретился делитель числа n 
| | | | |то simp:=нет 
| | | | все 
| | | кц 
| | | если simp 
| | | |то вывод нс, "Это число простое" 
| | | |иначе вывод нс, "Это число составное" 
| | | все 
| | все 
| все 
кон 

Можно ускорить вычисления и проверять делимость n на еще меньшее количество чисел - до квадратного корня из n. Если среди проверенных чисел нет делителей числа n, то их нет и среди остальных нечетных чисел. Можно также прекратить вычисления после того, как только встре-тился делитель числа n. С учетом этого приведенная выше программа мо-жет быть модифицирована путем замены имеющегося в ней цикла на следую-щий:

... 
simp:=да 
i:=3 
нц пока i<=int(sqrt(n)) и simp 
| если mod(n,i)=0                       |встретился делитель числа n 
| |то simp:=нет 
| |иначе i:=i+2 
| все 
кц 
...

а функция, проверяющая, является ли число n простым, и возвращаю-щая результат логического типа, имеет вид:

алг лог Simple(арг цел n) 
нач цел i, лог simp   |simp=нет, если встретится делитель числа n 
| если n=2 
| |то знач:=да                               |значение функции 
| |иначе 
| | если mod(n,2) = 0 
| | |то знач:=нет 
| | |иначе 
| | | simp:=да 
| | | i:=3 
| | | нц пока i<=int(sqrt(n)) и simp 
| | | | если mod(n,i)=0 
| | | | |то simp:=нет 
| | | | |иначе i:=i+2 
| | | | все 
| | | кц 
| | | если simp 
| | | |то знач:=да 
| | | |иначе знач:=нет 
| | | все 
| | все 
| все 
кон 

Язык Паскаль:

Uses CRT; 
Var  n: longint; 
Function  Simple(n:longint):boolean; 
Var i:longint;simp : boolean   { simp=false, если встретился делитель числа n} ; 
begin 
if n=2 then Simple:=true 
else if n mod 2 = 0 then Simple:=false 
else begin 
simp:=true; 
i:=3; 
while (i<=trunc(sqrt(n))) and  simp do 
      if n mod i =0 then simp:=false else i:=i+2; 
if simp then Simple:=true else Simple:=false 
end 
end; 

Основная часть программы:

BEGIN 
clrscr; 
readln(n); 
if Simple(n) then writeln('Yes') else writeln('No') 
END. 

Задача 2. Даны натуральные числа a,b (a<=b). Получить все простые числа p, удовлетворяющие неравенствам a<=p<=b.

Сделаем несколько предварительных замечаний.

Очевидно, что при решении задачи в качестве возможных "кандида-тов" в простые числа можно рассматривать только нечетные числа из ин-тервала a<=n<=b, а также число 2, если оно входит в этот интервал. За-метим также, что возможен случай a=1 и что число 1 простым не счита-ется (по определению).

Основные величины, используемые в программах (кроме величин a и b):

  • n - число, проверяемое на "простоту";
  • first - начальное значение этого числа;
  • simp - величина логического типа, в зависимости от которой дается ответ на вопрос, явля-ется ли число n простым.
  • k - количество найденных простых чисел в исследуемом интервале.

Основные этапы решения задачи:

  1. Ввод значений a и b.
  2. Проверка принадлежности числа 2 интервалу a<=2<=b (что возмож-но при a=1 или a=2).
  3. Определение значения first. Если a - четное число, то first=a+1, если нечетное - то first=3, если a=1 и first=a, если a>=3.
  4. Проверка всех нечетных чисел n от first до b и вывод на экран простых из них (с подсчетом значения k).

Если величина k=0, то это значит, что в указанном интервале простых чисел нет.

Приведем сначала программу с вложенными циклами.

  
Var a, b, n, first, k, i: integer; simp:boolean; 
BEGIN 
a:=2; b:=1;                               {условно для выполнения цикла} 
while a>b do     begin 
write('a='); readln (a); 
write('b='); readln (b); 
if a>b then writeln('Число a не должно быть больше числа b!') 
end; 
if (a=1) or (a=2) then         begin 
write(2,' '); 
k:=1 
end; 
if a mod 2 =0 then first:=a+1   {поиск начинаем с нечетного числа} 
else if a=1 then first:=3 
else first:=a; 
n:=first; 
while n<= b do begin 
simp:=True; 
i:=3;        {первый возможный делитель числа n} 
while (i<=trunc(sqrt(n))) and simp do 
if n mod i=0 then simp:=False 
else i:=i+2; 
if simp then  begin 
 write(n,' '); 
 k:=k+1 
end; 
n:=n+2 {поиск ведем только среди нечетных чисел} 
end; 
if k=0 then writeln('В этом диапазоне простых чисел нет') 
END. 

Читаемость приведенной программы значительно улучшается, если про-верку числа n на "простоту" проводить с помощью функции (процедуры), возвращающей результат логического типа. Эта функция отличается от описанной в Задаче 1, тем, что в ней иссле-дуются только нечетные числа.

Школьный алгоритмический язык:

  
алг лог Simple(арг цел n) 
нач цел i, лог simp  |simp=нет, если встретится делитель числа n 
| simp:=да 
| i:=3 
| нц пока i<=int(sqrt(n)) и simp 
| |  если mod(n,i)=0 
| |  |то simp:=нет 
| |  |иначе i:=i+2 
| |  все 
| кц 
| если simp 
| |то знач:=да 
| |иначе знач:=нет 
| все 
кон 

Язык Паскаль:

Var a,b,n,first,k:integer; 
Function Simple(n:integer):boolean; 
Var i:integer; 
simp:boolean; {simp=False, если встретится делитель числа n } 
begin 
simp:=True; 
i:=3; 
while (i<=trunc(sqrt(n))) and simp do 
if n mod i=0 then simp:=False 
else i:=i+2; 
if simp then Simple:=True else Simple:=False; 
end; 
BEGIN                   
a:=2; b:=1; 
while a>b do begin 
write('a='); readln (a); 
write('b='); readln (b); 
if a>b then writeln('Число a не должно быть больше числа b!') end; 
if (a=1) or (a=2) then begin 
write(2,' '); 
k:=1 
end; 
if a mod 2 =0 then first:=a+1 
else if a=1 then first:=3 
else first:=a; 
n:=first; 
while n< b do begin 
if Simple(n) then begin 
write(n,' '); 
k:=k+1 
end; 
n:=n+2 
end; 
if k=0 then writeln('В этом диапазоне простых чисел нет') 
END. 

Примечание. Во всех представленных программах случаи a=1,b=1 и a=1,b=2 не рассматривались.


Задача 3. Найти 100 первых простых чисел.

Как и в задаче 2, приведем сначала программы с вложенными циклами. Основные величины, используемые в программах:

  • n - число, проверяемое на "простоту";
  • simp - величина, назначение которой описано при разборе задачи 2;
  • k - количество найденных простых чисел.

Школьный алгоритмический язык:

алг Задача 3 
нач цел n,i,k,лог simp 
| вывод 2 
| k:=1 
| n:=3 
| нц пока k<100 
| | simp:=да 
| | i:=3 
| | нц пока i<=int(sqrt(n)) и simp 
| | | если mod(n,i)=0 
| | | |то   simp:=нет 
| | | |иначе i:=i+2 
| | | все 
| | кц 
| | если simp 
| | |то   вывод n 
| | |                           k:=k+1 
| | все 
| | n:=n+2 
| кц 
кон 

Язык Паскаль:

Var n,k,i:integer; simp:boolean; 
BEGIN write(2,' '); k:=1; n:=3; while k<100 do 
begin 
simp:=True; i:=3; 
while (i<=trunc(sqrt(n))) and simp do if n mod i=0 then simp:=False else i:=i+2; 
if simp then  begin 
write(n,' '); 
k:=k+1 
end; 
n:=n+2 
end; 
END. 

Программа, использующая функцию:

  
Var n,k:integer; 
Function Simple(n:integer):boolean; 
... см. задачу 2 
end; 
BEGIN                               {Основной части программы} 
write(2,' '); k:=1; 
n:=3; 
while k< 100 do begin 
if Simple(n) then begin 
write(n,' '); 
k:=k+1 
end; 
n:=n+2 
end; 
END. 

Имеется еще один метод решения рассматриваемой задачи. Он заключается в том, что все найденные простые числа хранятся в некотором массиве, а делимость очередного кандидата проверяется только на числа из этого массива. При этом уменьшается количество возможных делителей, что приводит к ускорению работы программы. Причем и эту проверку можно ускорить, если проверять делимость очередного числа n только на те элементы массива, значение которых не больше квадратного корня из n. Данный метод особенно эффективен в тех случаях, когда необходимо найти большое количество простых чисел.

Приведем программы, в которых применяется этот метод.

Назначение величин k, n и simp в программах аналогично описанному выше. Дополнительно используемые величины:

  • find - массив найденных простых чисел (из 100 элементов);
  • limit - величина, равная квадратному корню из n.

Школьный алгоритмический язык:

алг Задача 3 
нач цел n,i,k, цел таб find[1:100], лог simp, цел limit 
| find[1]:=2;                        |записываем в массив простых чисел одно известное 
| вывод 2 
| k:=1                               |число найденных простых чисел 
| n:=3;                              |первый "кандидат" в простые числа 
| нц пока k<100 
| | limit:=int(sqrt(n)) 
| | simp:=да 
| | i:=1 
| | нц пока i<=k и simp и find[1]<=limit |условие проверки делимости 
| | | если mod(n,find[i])=0 
| | | |то simp:=нет 
| | | |иначе i:=i+1 
| | | все 
| | кц 
| | если simp 
| | |то 
| | | вывод n                         |n - простое число 
| | | k:=k+1;                         |добавляем найденное n 
| | | find[k]:=n                      |в массив простых чисел 
| | все 
| | n:=n+2                            |следующий кандидат в простые числа 
| кц 
кон 

Язык Паскаль:

Var n,i,k:integer; find:array[1..100] of integer; simp:boolean; limit:integer; 
BEGIN 
find[1]:=2;              {записываем в массив простых чисел одно известное} 
write(2,' '); 
k:=1;                    {число найденных простых чисел} 
n:=3;                    {первый "кандидат" в простые числа} 
while k<100 do 
begin 
limit:=trunc(sqrt(n)); 
simp:=true; 
i:=1; 
while (i<=k) and  simp=true and (find[i]<=limit) 
{условие проверки делимости числа n} 
do if n mod find[i]=0 then simp:=false else i:=i+1; 
if simp then begin 
write(n,' ');     {n - простое число} 
k:=k+1;     {добавляем найденное n} 
find[k]:=n     {в массив простых чисел} 
end; 
n:=n+2                        {следующий кандидат в простые числа} 
end 
END. 

Задача 4. Дано четное число n>2; проверить для этого числа гипотезу Гольдбаха. Эта гипотеза (по сегодняшний день не опровергнутая и пол-ностью не доказанная) заключается в том, что каждое четное n, большее двух, представляется в виде суммы двух простых чисел. Определить про-цедуру, позволяющую распознавать простые числа).

Для проверки гипотезы следует определить, имеются ли среди пар чисел 2 и n-2, 3 и n-3,..., n-2 и 2 такие, что числа, их составляющие, - простые.

Приведем сначала программу на школьном алгоритмическом языке. Ве-личины, используемые в ней:

  • n - число, применительно к которому проверяется гипотеза;
  • item1 - первое число в перечисленных парах чисел;
  • k - число пар с простыми составляющими (очевидно, что это число может быть больше 1, например, для n=10: 3 и 7, 5 и 5, 7 и 3).

В программе используется функция Simple, "распознающая" простые числа, описанная в Задаче 1.

алг Задача 4 
нач цел n,item1, k 
| n:=1                               |условно  для выполнения цикла 
| нц пока mod(n,2)=1 
| | вывод нс,"n=" ; ввод n 
| | если  mod(n,2)=1 
| | |то 
| | | вывод нс,"Число n должно быть четным!" 
| | все 
| кц 
| item1:=3; k:=0 
| нц для  item1 от 2 до n-2 
| | если Simple(item1) и Simple(n-item1) 
| | |то  k:=k+1 
| | все 
| кц 
| если k>0 
| |то  вывод нс,"Для данного n гипотеза справедлива" 
| |иначе вывод нс,"Для данного n гипотеза не справедлива" 
| все 
кон 

Существенного сокращения числа вычислений можно достичь, если учитывать, что:

  • для n>4 возможные значения п р о с т ы х составляющих пар - нечетные числа, т.к. единственным простым четным числом является 2;
  • можно рассматривать значения item1 только до n/2 (если в этом интервале нет пар чисел с простыми item1 и n-item1, то их нет и среди остальных значений item1).
  • можно прекратить вычисления как только будет найдена первая пара простых чисел.

В программах использована величина hypot логического типа, от ко-торой зависит ответ на вопрос о справедливости гипотезы Гольдбаха. В случае положительного ответа на экран выводится также первая найденная пара простых слагаемых item1 и n-item1.

Школьный алгоритмическй язык:

алг лог Simple(арг цел n) 
нач ... 
см. выше 
кон 
алг Задача 4 
нач цел n,item1, лог hypot 
| n:=1 
| нц пока mod(n,2)=1 или n<4 
| | вывод нс,"n=" ; ввод n 
| | если  mod(n,2)=1 
| | |то 
| | | вывод нс,"Число n должно быть четным!" | | все 
| | если n<4 
| | |то 
| | | вывод нс,"Число n должно быть >2!" 
| | все 
| кц 
| hypot:=нет 
| если n=4 
| |то                               |проверим и число 4 
| | item1:=2 
| | hypot:=да 
| |иначе                               |n>4 
| | item1:=3 
| | нц пока item1<=div(n,2) и не hypot 
| | | если Simple(item1) и Simple(n-item1) 
| | | |то  hypot:=да 
| | | |иначе item1:=item1+2 
| | | все 
| | кц 
| все 
| если hypot 
| |то  вывод нс,"Для данного n гипотеза справедлива" 
| |                вывод нс,"Простыми слагаемыми являются числа", item1,"и",n-item1 
| |иначе вывод нс,"Для данного n гипотеза несправедлива"" 
| все 
кон 

Язык Паскаль:

Var n,item1:integer; hypot:boolean; 
Function Simple(n:integer):boolean; 
Var i:integer; 
simp:boolean;  {simp=False, если встретится делитель числа n} 
begin 
if n=2 then Simple:=True 
else if n mod 2=0 then Simple:=False 
else  begin 
simp:=True; 
i:=3; 
while (i<=trunc(sqrt(n))) and simp do 
if n mod i=0 then simp:=False 
else i:=i+2; 
if simp then Simple:=True else Simple:=False; 
end; 
end; 
BEGIN 
n:=1;                               {условно для выполнения цикла} 
while n mod 2 = 1 do                          
begin 
write('n='); readln (n); 
if n mod 2 = 1 then writeln('Число n должно быть четным!') 
end; 
hypot:=False; 
if n=4 then begin                               {проверяем и число 4} 
item1:=2; 
hypot:=True 
end 
else  begin                             {n>4} 
item1:=3; 
while (item1<=n div 2) and not hypot do 
if Simple(item1) and Simple(n-item1) then hypot:=True 
else item1:=item1+2 
end; 
if hypot  then 
begin 
writeln('Для данного n гипотеза справедлива'); 
writeln('Простыми слагаемыми являются числа ',item1,' и ',n-item1) end 
else writeln('Для данного n гипотеза не справедлива'); 
END. 

Задача 5. Дано натуральное число n. Выяснить, имеются ли среди n, n+1, ..., 2n близнецы, т.е. простые числа, разность между которыми равна двум. (Определить процедуру, позволяющую распознавать простые числа).

Величины, используемые в программах (кроме величины n): m - число, проверяемое на "простоту";

  • first - начальное значение этого числа;
  • k - число пар "близнецов", найденных в рассматриваемом интервале.

Основные этапы решения задачи:

  • Ввод значения n.
  • Определение значения first (см. задачу 1).
  • Поиск чисел-близнецов среди нечетных чисел m от first до 2n и вывод их на экран (с подсчетом количества).

Школьный алгоритмический язык:

алг лог  Simple(арг цел n) 
нач ... 
см. задачу 1 
кон 
алг Задача 5 
нач цел n, first, m, k 
| вывод нс,"n=" ; ввод n 
| вывод нс, "Числа-близнецы" 
| если mod(n,2)=0 
| |то first:=n+1                               |поиск начинаем с нечетного числа 
| |иначе first:=n 
| все 
| k:=0 
| нц для m от first до 2*n-2  шаг 2    |и ведем среди таких же чисел 
| | если Simple(m) и Simple(m+2) 
| | |то вывод m,"и",m+2 
| | |   k:=k+1 
| | все 
| кц 
| если k=0                               |например, при  n=6 
| |то вывод "в рассматриваемом диапазоне отсутствуют" 
| все 
кон 

Язык Паскаль:

Var n,m,first,k:integer; 
Function Simple(n:integer):boolean; 
... (см. задачу 2) 
end; 
BEGIN                   
write('n='); readln (n); 
write('Числа-близнецы '); 
if n mod 2 =0 then first:=n+1 
else first:=n;                   {поиск начинаем с нечетного числа} 
m:=first; 
while m<2*n-2 do 
begin 
if Simple(m) and Simple(m+2) then 
begin 
write(m,' и ',m+2,' '); 
k:=k+1 
end; 
m:=m+2              {и ведем среди таких же чисел} 
end; 
if k=0                               {например, при  n=6} 
then write('в рассматриваемом диапазоне отсутствуют') 
END. 

Примечание. В условии задачи требовалось только ответить на вопрос, имеются ли близнецы в указанном диапазоне чисел. При необходи-мости строгого соблюдения условий задачи можно не выводить найденные значения близнецов на экран, а выводить только ответ на вопрос в за-висимости от значения k. При этом можно также прекратить поиск после нахождения первой пары чисел-близнецов.

Нетрудно заметить, что в представленных программах значение функции (или величины) Simple для каждого значения m определяется дважды, что нерационально. Этот недостаток можно устранить, если использовать величину was_simple логического, определяющую, являлось ли простым число, пред-шествовавшее расcматриваемому числу m. Естественно, что в этом случае следует проверять значения m до 2n, а не до 2n-2, как это делалось ра-нее.

Школьный алгоритмический язык:

алг лог  Simple(арг цел n) 
нач ... 
см. выше 
кон 
  
алг Задача 5 
нач цел n,first,m,k, лог was_simple 
| вывод нс,"n=" ; ввод n 
| вывод нс, "Числа-близнецы" 
| если mod(n,2)=0 
| |то first:=n+1 
| |иначе first:=n 
| все 
| k:=0 
| was_simple:=нет 
| нц для m от first до 2*n шаг 2 
| | если Simple(m) 
| | |то 
| | | если was_simple 
| | | |то 
| | | | вывод m-2,"и",m 
| | | | k:=k+1 
| | | все 
| | | was_simple:=да 
| | |иначе 
| | | was_simple:=нет 
| | все 
| кц 
| если k=0 
| |то вывод "в рассматриваемом диапазоне отсутствуют" | все 
кон 

Язык Паскаль:

Var n,m,first,k:integer; was_simple:boolean; 
Function Simple(n:integer):boolean; 
... см. выше 
end; 
BEGIN                   
write('n='); readln (n); 
write('Числа-близнецы '); 
if n mod 2 =0 then first:=n+1 
else first:=n; 
m:=first; 
while m<2*n do 
begin 
if Simple(m)  then begin 
if was_simple then 
begin 
write(m-2,' и ',m,' '); k:=k+1 
end; 
was_simple:=True 
end 
else was_simple:=False; 
m:=m+2 
end; 
if k=0 then write('в рассматриваемом диапазоне отсутствуют')
end.
Дмитрий Михайлович Златопольский
mailto:zlato@orc.ru

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
288
19 ноября 2005 года
sadovoya
757 / / 19.11.2005
Мне нравитсяМне не нравится
3 мая 2013, 18:35:04
Статья полезная но нет доказательств принимаемых для оптимизации методов.

Попробую восполнить для простых чисел.

Итак имеем по определению: простое число -- целое число большее 1 и которое делится без остатка только на 1 и на себя. Т.е. простые числа: 2, 3, 5, 7 и т.д.

Для оптимизации алгоритмов проверки простых чисел можно использовать несколько соображений (применяются в статье, здесь привожу с доказательством):

1)Простое число -- нечетное число (за исключением числа 2, которое простое).
Доказательство очевидно, поскольку все четные кратны двум, а значит уже делимы
без остатка хотя бы на двушку.

2)Если число составное, то его можно представить в виде произведения целых a=m*M;
значит корень(a)=корень(m*M), т.е. сред. геометрическому; значит корень(а) лежит
между m и M. Поэтому, "забраковать" число как не простое можно выполнив проверки
лишь для чисел <= корня от него.

3)Нечетное число делится на четное с остатком. Действительно, предположим,
что верно обратное, тогда нечетное (2m+1) при делении на четное (2n) должно
дать целое (k), т.е. (2m+1)/(2n) = k. Это равносильно тому, что (2m+1)=2nk.
Но 2nk четное. Получили противоречие: нечетное равно четному.

Ну и пример от себя на C++ в обобщение сказанного:

Функция проверки простых чисел.
[code/]

bool prime(int c) {
if (c < 2) return false;
if (c == 2) return true;
if (!(c % 2)) return false;

//цикл по нечетным от 3 до i=корень(с);
//c=3, 5 и 7 этот цикл пропустят, но им
//можно - они простые :)
for (int i = 3; i*i <= c; i+=2)
if (!(c % i))
return false;

return true;
}

[/code]

Здесь сравнение с корнем заменено на более быструю эквивалентную конструкцию
i*i <= c (равносильно i<=корень(с))
1.1.
288
19 ноября 2005 года
sadovoya
757 / / 19.11.2005
Мне нравитсяМне не нравится
3 мая 2013, 20:02:42
Поправлю сам себя. Лучше все-таки так:

bool prime(int c) {
if (c < 2) return false;
if (c == 2) return true;
if (!(c % 2)) return false;

//один раз корень посчитать быстрее, чем i*i сравнивать с c в цикле
int im = (int)sqrt(c) + 1; //+1 чтобы не писать <= im
for (int i = 3; i < im; i+=2)
if (!(c % i)) return false;

return true;
}
1.1.1.
288
19 ноября 2005 года
sadovoya
757 / / 19.11.2005
Мне нравитсяМне не нравится
3 мая 2013, 22:31:36
Совсем плохой стал :) В последнем варианте косяк (приведением к int может усечься и в меньшую сторону). Правильно так:

bool prime(int c) {
if (c < 2) return false;
if (c == 2) return true;
if (!(c % 2)) return false;
int im = (int)ceil(sqrt(c)) + 1; //+1 чтобы не писать <= im;
//c=3 этот цикл пропустит, но ей можно (3-простое)
for (int i = 3; i < im; i+=2)
if (!(c % i)) return false;

return true;
}
2.
Аноним
+1 / -1
Мне нравитсяМне не нравится
1 июня 2006, 14:21:20
Этот достаточно простой алгоритм (и даже образец кода на Паскале) исчерпывающе описан в теме: "Просеивание числового песка в поисках простых чисел".
3.
Аноним
+3 / -1
Мне нравитсяМне не нравится
14 апреля 2005, 17:03:57
помогите написать алгоритм "найти все простые числа в диапазоне от 1 до N"
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог