数论知识

数论的知识与信息学竞赛关系密切相关,尤其是初等数论。初等数论是用初等数学方法来研究整数的整除、同余式等方面问题的数论分支。其内容包括辗转相除法、进位制、因数、倍数、公因数、公倍数、最大公因数、最小公倍数、素数、合数等。

一、素数与整除问题

1、素数和合数

大于1的正整数p,如果p仅有的正因子是1p,则称p为素数;大于1且不是素数的正整数称为合数。如果n是合数,则必有一个小于等于的素因子。

2、整数和约数

如果ab是整数,若有整数c使b=ac,就说a整除b。在a整除b时,记ab的一个因子(约数)ba的倍数。符号a|b表示a整除b。整数可整除性的基本性质有:

①若a|b,a|c,则a|(b+c)

②若a|b,那么对所有整数ca|bc;

③若a|b,b|c,a|c;即整数整除具有传递性。

3、素数的求法

2~n之间的素数。

方法一 根据素数的定义我们给出它的算法:

       for i:=2 to n do

         begin

       1. 用2到去除i,看能否除尽

          flag:=true

          for j:=2 to round(sqrt(i))

            if i mod j=0 then flag:=false

        2.if 除不尽 then 输出素数i。

参考程序

var n,i,j,count:integer;

    flag:boolean;

begin

  write(‘input n:’);

  readln(n);

  count:=0;

  for i:=2 to n do

    begin

      flag:=true;

      for j:=2 to round(sqrt(i)) do

        if i mod j=0 then flag:=false;

       if flag

       then begin

              write(i,′ ′);

              count:=count+1;

              if count mod 5=0 then writeln;

            end;

      end;

end.

方法二 用筛选法求素数,算法如下:

       1.建立[2..n]的集合

       2.repeat

         找出当前集合中的最小数(即素数)

         打印该最小数

         从集合中减去该素数的所有倍数

         UNTIL集合为空

参考程序

const maxn=10000;

var

  sieve:set of 1..maxn;

  next,mul,n:integer;

begin

  readln(n);

  sieve:=[2..n];

  next:=2;

  repeat

  while not(next in sieve) do

    next:=next+1;

  write(next:3);

  mul:=next;

  while mul<=n do

    begin 

      sieve:=sieve-[mul];

      mul:=mul+next;

    end;

  until sieve=[ ];

end.

二、最大公约数和辗转相除法、最小公倍数

1、除法的定义和同余

令a为整数,d正整数,那么有惟一的整数q和r,其中0≤r<d,使得a=bq+r。可以用这个定理来定义除法:d叫除数,a叫被除数,q叫商,r叫余数。如果两个数a,b除以一个数c的余数相等,则说a和b关于模c同余,记作a≡b(mod c)。

2、最大公约数和最小公倍数

令a和b是不全为0的两个整数,能使d|a和d|b的最大整数称为a和b的最大公约数,用gcd(a,b)表示。令a和b是不全为0的两个整数,能使a|d和b|d的最小整数称为a和b的最小公倍数,用lcm(a,b)表示。令a和b为正整数,则有ab=gcd(a,b)×lcm(a,b)。

3、辗转相除法

用辗转相除法求最大公约数:利用gcd(a,b)=gcd(b,a mod b)(a>b)进行迭代,算法如下:

function gcd(a,b:longint):longint;

  begin

    if b=0 then gcd:=a

    else gcd:=gcd(b,a mod b);

   end;

 例2 最大公约数与最小公倍数问题。

 输入二个正整数x0,y0(2≤x0<100000,2≤y0≤1000000),求出满足下列条件的p,q的个数:

①p,q是正整数;②要求p,q以x0为最大公约数,以y0为最小公倍数。

试求:满足条件的所有可能的两个正整数的个数。

算法分析

⑴如何判别两个自然数素质

x和y的最大公约数为gcd(x,y)=

    

function gcd(x,y:longint):longint;

  begin

    if y=0 then gcd:=x

           else gcd:=gcd(y,x mod y);

  end;{gcd}

显然,gcd(x,y)=1是x与y互质的标志。除1以外的任何自然数n都可以惟一的分解成质数的乘积:

n=p1l1*p2l2*…*pklk是(质数p1<p2<…<pk,质数的次幂l1,l2,…,lk>0)

⑵如何计算以x0为最大公约数,以y0为最小公倍数的(p,q)个数

明确几个问题:

①若y0不能整除x0,则不存在以x0为最大公约数、以y0为最小公倍数的(p,q);

②若x0=y0,则p=q=x0=y0,即满足条件的p和q仅为一对(x0,y0);

③若x0≠y0且y0整除x0,则满足条件的p和q一定为偶数对。

设=n=1*p1l1*p2l2*…*pklk

若分解出k个质数的乘积的话,则满足条件的p和q的个数有:

      

 

 

 

 

tot:=0;                       {tot为记录满足条件的(p、q)个数}

if y0 mod x0=0                {若y0不能整除x0,则不存在满足条件的(p,q)}

  then begin

         y:=y0 div x0;

  {计算=n=1* p1l1*p2l2*…*pklk,确定满足条件的p和q的个数有                }

 

        

 

 

for i:=1 to trunc(sqrt(y)) do

           if (y mod i=0) and (gcd(i,y div i)=1) then inc(tot,2);

         if y=1 then dec(tot);   {若x0=y0,则(x0,y0)即为满足条件的(p,q)}

       end;{then}

输出满足条件的(p,q)个数tot。

参考程序:

var tot,x0,y0,i,y:longint;

function gcd(x,y:longint):longint;

  begin

    if y=0 then gcd:=x

    else gcd:=gcd(y,x mod y);

  end;

begin

  tot:=0;

  readln(x0,y0);

  if y0 mod x0=0

    then begin

           y:=y0 div x0;

           for i:=1 to trunc(sqrt(y)) do

             if (y mod i=0) and (gcd(i,y div i)=1) then inc(tot,2);

           if y=1 then dec(tot);

         end;

  writeln(tot);

end.

 

posted @ 2010-10-11 21:25  lj_cherish  阅读(714)  评论(0编辑  收藏  举报