算法教程2

 
编程入门题(二)
1、求素数:求2至N(2≤N≤500)之间的素数。例如:
输入:N=100
输出:  2   3    5   7  11  13
       17  19   23  29  31  37
       41  43   47  53  59  61
       71  73   79  83  89  97
       total=24   {表示2至100之间的素数有24个}
[解法一]素数是指除1及本身以外不能被其他数整除的自然数。下面介绍用穷举法求素数。
1.2是素数;t=0;
2.I=2~n,则:
(1)如果i是素数,则其必须是奇数且不能被2~√i  中的任一个数整除。
     (2)如果I是素数,则输出该素数且计数器t=t+1;
   3.输出2~N之间素数的总数:total=t;
4.程序结束
[程序]
program exa;
uses crt;
var  i,k,n,w,t:integer;
     yes:boolean;
Begin t:=0;clrscr;write(‘N=’);readln(n);
  if (n<2)and(n>500) then
    begin writeln(‘input error!’);halt;end;
  write(2:5);t:=1;
  for i:=2 to n do
    if odd(i) then
      begin yes:=true;
        w:=trunc(sqrt(I));k:=2;
        while (k<=w)and yes do
          begin if i mod k=0 then yes:=false; k:=k+1;end;
        if yes then begin write(i:5);t:=t+1; end;
      end;
  writeln(‘total=’,t);
end.
[解法二]筛法求素数:
    1.建立一个包括2,3,…,N的数据“集合”R;
    2.顺序取R中的数(从素数2开始),同时将其及能整除它的数从R中划去。“筛法求素数”的过程如下图示:
素数R[1]               数据集合R
   2{ 2, 3, 4, 5, 6, 7, 8,  9,10,11,12,……}
   3{     3,     5,      7,    9,     11,   ……}
   5{             5,      7,            11,   ……}
……                 ………
    这样便可得到所求的素数:2,3,5,……。
[程序]
program Sushu;
var  i,j,k,n,w,t:integer;
  R,P:array [1..500] of integer;
Begin
  write(';N=';);readln(n);
  if (n<2) or (n>500) thenbegin writeln(';Input N error!';);halt end;
  for i:=2 to n do R[i-1]:=i; writeln(';Result:';);t:=0;k:=n-1;
  while k>0 do
    begin P:=R;  {数组P保存在P中}
      write(R[1]:5);  {输出素数} t:=t+1;w:=R[1];j:=0;
      for i:=1 to k do
        if P mod w<>0 then  {划去w及 W的倍数}
          begin j:=j+1; R[j]:=P;end;  {重新构造集合R}
      k:=j; {新建后R的元素个数}
    end;  writeln;writeln(';Total=';,t);
end.
2、矩阵相乘:已知N×M1矩阵A和M1×M矩阵B(1≤M、M1、N≤10),求矩阵C(=A×B)。例如:
输入:N,M1,M=4  3  4
      A= 1   2    3            
34    5             提示:所谓矩阵相乘(如A×B=C),是指
45    6                Cij= ∑(Aik×Bkj)(i=1~N,j=1~M1,k=1~M)
5–1  –2                  
           B= 1   6    4    2        例如:
              2   3    4    1             C11=A11×B11+A12×B21+A13×B31
            –1   5    7   –3              =1×1+2×2+3×(– 1)
输出:C= 2   27   33   –5             =2
              6   55   63   –5            C42= A41×B12+A42×B22+A43×B32
              8   69   78   –5              =5×6+(–1)×3+(–2)×5
         5   17   2    15               =17
[解]该题主要考查矩阵的表示及其运算。矩阵A(N×M1)与矩阵B(M1×M)相乘得矩阵C(N×M),其解法如下:
       i=1~N,重复做
         j=1~M,重复做
     (1)cij=0; (2)k=1~M1,重复做Cij=Cij+Aik*Bkj; (3)输出Cij
[程序]
program JiZheng;
var i,j,k,N,M1,M:integer;
A,B,C:array [1..10,1..10] of integer;
Begin
  write(';N,M1,M=';);readln(N,M1,M);
  if (N>=1)and(N<=10)and(M1>=1)and(M1<=10)and(M>=1)and(M<=10) then
begin {输入N×M1矩阵A}write(';A=';);
for i:=1 to N do for j:=1 to M1 do read(A[i,j]);readln;
    {输入M1×M矩阵B} write(';B=';);
for i:=1 to M1 do for j:=1 to M do read(B[i,j]);readln;
    write(';C=';);
      for i:=1 to N do
        begin for j:=1 to M do{计算Cij= ∑(Aik×Bkj)}
          begin C[i,j]:=0; for k:=1 to M1 do C[i,j]:=C[i,j]+A[i,k]*B[k,j];
            write(C[i,j]:5); {输出矩阵Cij}
          end;
          writeln;write('; ';:2);
        end;
      writeln;
    end
  else writeln(';Input N,M1,M error!';);
end.
3、找数字对:输入N(2≤N≤100)个数字(在0与9之间),然后统计出这组数中相邻两数字组成的链环数字对出现的次数。例如:
输入:N=20  {表示要输入数的数目}
      0  1  5  9  8  7  2  2  2  3  2  7  8  7  8  7  9  6  5  9   
输出:(7,8)=2 (8,7)=3 {指(7,8)、(8,7)数字对出现次数分别为2次、3次)
     (7,2)=1 (2,7)=1
     (2,2)=2
     (2,3)=1 (3,2)=1
[解]该题主要是数组的存储表示及运用。数组A存放所输入的N个数,用数组B表示A 与A[i+1]相邻数字对出现的次数。计算过程见下表:
数组A次数i0  1  5   9  8   7   2   2   2   3  2   7   8   7   8   7   9    6  5   9 1  2   3  4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19
求链环数字的过程I= 1: B[0,1]=1      I=2:B[1,5]=1      I=3: B[5,9]=1     I=4: B[9,8]=1 I= 5: B[8,7]=1      I=6:B[7,2]=1      I=7: B[2,2]=1     I=8: B[2,2]=2 I=9: B[3,2]=1      I=10:B[2,3]=1     I=11:B[2,7]=1      I=12:B[7,8]=1     I=13:B[8,7]=2      I=14:B[7,8]=2     I=15:B[8,7]=3      I=16:B[7,9]=1     I=17:B[9,6]=1      I=18:B[6,5]=1     I=19:B[5,9]=1
[程序]
Program Getdouble;
var i,N:integer; fd:boolean;
  A:array[1..100] of integer;
  B:array[0..9,0..9] of integer;
Begin fillchar(B,sizeof(B),0);{数组B初值置为0} write(';N=';);readln(N);
  if (N>1)and(N<=100) then
    begin write(';Enter ';,N,'; numbers:';);
      for i:=1 to N do
        begin read(A);  {输入A}
          if (A<0)or(A>9) then   {A的值在0与9之间}
            begin writeln(';Input error!';);halt;end;
        end;
      for i:=1 to N-1 do
        B[A,A[i+1]]:=B[A,A[i+1]]+1;{相邻数字对BA,A[i+1]值加1}
      fd:=true;writeln(';Result:';);
      for i:=1 to N-1 do
        if (B[A,A[i+1]]>0)and(B[A[i+1],A]>0) then
          begin write(';(';,A,';,';,A[i+1],';)=';,B[A,A[i+1]],';  ';);
            if A[i+1]=A then writeln {相邻数字相同,如(2,2)}
              else writeln(';(';,A[i+1],';,';,A,';)=';,B[A[i+1],A]);
            B[A[i+1],A]:=0;
            fd:=false;
          end;
      if fd then writeln(';Not found!';);
    end
  else writeln(';Input N error!';);
end.
4、蛇形矩阵:生成一个按蛇形方式排列自然数1,2,3,4,5,……,N2的 (1<N≤10)阶方阵。例如:
输入:N=4                         N=7
输出:1   3    4   10               1    3    4   10   11   21   22
           2   5    9   11               2    5    9   12   20   23   34
           6   8   12   15               6    8   13   19   24   33   35
           7   13  14   16               7   14   18   25   32   36   43
                                        15   17   26   31   37   42   44
                                        16   27   30   38   41   45   48
                                        28   29   39   40   46   47   49
[解]本题考查重点是矩阵的表示及
    上下标运算,旨在培养观察和
    分析思维能力。
        例如,当N=7 时,把1,
    2,3,……,49逐一填入数组
    A中,搜索填数的方向如右图示:
    从图中,我们可以看出:对每个数字m(1,2,……,~N*N)来说,可能按以下四种搜索方向之一填数:
                              d=2(右上)
   
                      m        d=3(向右)
           d=4        
         (左下)        d=1(向下)
    按照图10-1的搜索方向填数时,先要把当前数字m填入数组A[i,j]中,接下来就是要确定下一次的填数的坐标及其搜索方向(即d=?)。现分析如下:
    第一种情形(d=1,如m=2,7,15;35,44):
              (i,j)
            d=1        d=2(当j=1)
              (i+1,j)
               
                d=4(当j=N)
    第二种情形(d=2,如m=2,10,21;或34,43,48;或7,8,9,16,17,18,19等):
                    d=2(当i<>1且j<>N)
                 
             (i-1,j)     d=3(当i=1)
               
          d=2       d=1(当j=N)
          (i,j)
    第三种情形(d=3,如m=29,40,47;或4,11,22):
                    d=3          d=2(当i=N)
             (i,j)     (i,j+1)
               
                     d=4(当j=N)
    第四种情形(d=4,如m=28,39,46;或6,15;或5,12,13,14等):
                     (i,j)
                      d=4
              (i+1,j)     d=3(当i=1)
               
                d=4(当i=N且j<>1)
[程序]
Program she;
const max=10;
var d,i,j,m,N:integer;
  A:array [1..10,1..10] of integer;
begin
  write(';N=';);readln(N);
  if (N>=1) and (N<=max) then
    begin i:=1;j:=1;m:=1;d:=1;
      repeat A[i,j]:=m;   {填数}
        case d of
          1: {第一种情形}begin i:=i+1; if j=1 then d:=2 else d:=4; end;
          2: {第二种情形}begin i:=i-1;j:=j+1;
if j=N then d:=1 else if i=1 then d:=3;end;
          3: {第三种情形}begin j:=j+1; if i=N then d:=2 else d:=4;end;
          4: {第三种情形}begin i:=i+1;j:=j-1;
if i=N then d:=3 else if j=1 then d:=1;end;
        end;
        m:=m+1;
      until m>N*N;
      writeln(';OUTPUT:';);
      for i:=1 to N do begin for j:=1 to N do write(A[i,j]:4); {输出填数} writeln;end;
    end
  else writeln(';Input N error!';);
end.
5、编码问题(95年全国分区联赛题):设有一个数组A:array [0..N-1] of integer; 存放的元素为0~N-1(1<N<=10)之间的整数,且A ≠A[j](i≠j)。例如当N=6时,有:A=(4,3,0,5,1,2)。此时,数组A的编码定义如下:
A[0]编码为0;
A编码为:在A[0],A[1],…,A[i-1]中比A的值小的个数
          (i=1,2,…,N-1)
∴上面数组A的编码为:B=(0,0,0,3,1,2)
    要求编程解决以下问题:
(1)给出数组A后,求出其编码;
(2)给出数组A的编码后,求出A中的原数据
程序样例:
例一:
输入:Stat=1   {表示要解决的第(1)问题}
       N=8      {输入8个数}
       A=1 0 3 2 5 6 7 4
输出:B=0 0 2 2 4 5 6 4
例二:
输入:Stat=2   {表示要解决的第(2)问题}
       N=7
       B=0 1 0 0 4 5 6  
输出:A=2 3 1 0 4 5 6

[解]第1个问题的解法:用穷举搜索法。
      B[0]为0
      B表示在A[1],A[2],……,A[i-1]中比A(i=1,2,……,N)小的个数。
    第2个问题的解法:先构建数组P,初始值为0,1,2,3,……,N-1。然后从B[N-1],B[N-2],……,B[1],B[0]逆向从数组P中取数求数组A。以题中例二为例,求解过程如下图:
下标值iB0 B1 B2  B3 B4  B5 B6 p0 p1 p2  p3 p4  p5  p6数组A
   60 1  0  0  4  5  6                ↑0  1  2  3  4  5  6A[6]=p[B6]=p6=6,划去p6
   50 1  0  0  4  5  6             ↑    0  1  2  3  4  5A[5]=p[B5]=p5=5,划去p5
   40 1  0  0  4  5  6          ↑      0  1  2  3  4 A[4]=p[B4]=p4=4,划去p4
   30 1  0  0  4  5  6       ↑         0  1  2  3   A[3]=p[B3]=p0=0,划去p0
   20 1  0  0  4  5  6    ↑            1  2  3  A[2]=p[B2]=p0=1,划去p0
   10 1  0  0  4  5  6 ↑               2  3  A[1]=p[B1]=p1=3,划去p2
   00 1  0  0  4  5  6↑                 2   A[0]=p[B0]=p0=2
    从上述求解过程中,我们得到:A=(2,3,1,0,4,5,6)。
[程序]
program code;
var  i,j,k,m,n,stat:integer;
  A,B,P:array [0..10] of integer;
begin
  write(';Stat(1,or 2)=';);readln(stat);
  case stat of
    1:begin write(';N=';); readln(n); write(';A=';);
        for i:=0 to n-1 do read(A); readln; {读入数组A}
        for i:=0 to n-2 do  
          for j:=i+1 to n-1 do
            if (A=A[j])or(A>n-1) then {数组A中有否相等}
              begin writeln(';Input error!';);halt; end;
        for i:=0 to n-1 do B:=0; {编码数组B初始值为0}
        for i:=1 to n-1 do
          for j:=0 to i-1 do
            if A>A[j] then B:=B+1; {求数组编码}
        for i:=0 to n-1 do write(B:5);writeln;
      end;
    2:begin write(';N=';); readln(n); write(';B=';);
        for i:=0 to n-1 do read(B); readln; {读编码数组B}
        for i:=0 to n-1 do P:=i; {建立取数数列P}
        for i:=n-1 downto 0 do  {由编码数组B逆向求原数组A}
          begin A:=P[B];  {A为数组P中第B号元素}
            for j:=B to i-1 do P[j]:=P[j+1];{从P数组中删去P[B]}
          end;
        write(';A=';);
        for i:=0 to n-1 do write(A:5);writeln; {输出数组A}
      end;
  end;
end.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值