算法题及源程序Word格式.docx
《算法题及源程序Word格式.docx》由会员分享,可在线阅读,更多相关《算法题及源程序Word格式.docx(48页珍藏版)》请在冰豆网上搜索。
![算法题及源程序Word格式.docx](https://file1.bdocx.com/fileroot1/2022-12/14/cd086de9-c542-44d4-81f6-dee48905f4ba/cd086de9-c542-44d4-81f6-dee48905f4ba1.gif)
=2to333do
beginl:
=lcm(m,667-m);
{求最小公倍数}
g:
=gcd(m,667-m);
{求最大公约数}
if(l=g*120)and(lmodg=0)then
writeln(m:
5,667-m:
5);
end;
End.
第二层考虑函数lcm(最小公倍数)、gcd(最大公约数)的细化。
最大公约数问题是对参数a、b,找到一个数i能整除a与b,i就是gcd的函数值。
Functiongcd(a,b:
integer):
vari:
beginfori:
=adownto1do
ifnot((amodi=0)or(bmodi=0))thengcd:
=i;
而最小公倍数的计算是:
若干个b之和,若能被a整除,则该和便是a、b的最小公倍数。
Functionlcm(a,b:
begini:
=b;
whileimoda=0doi:
=i+b;
lcm:
第二节编程入门题例
编程入门题
(一)
1、位数对调:
输入一个三位自然数,把这个数的百位与个位数对调,输出对
调后的数。
例如:
Input3bitnatruedata:
234n=432[解]1.先确定输入数n是否三位数,即n>
99且n<
=999。
2.位数对调:
n=abc→cba=x①百位数a=n整除100;
②十位数b=(n-a*100)整除10;
③个位数c=n除以10的余数;
3.得对调后的数:
x=c*100+b*10+a
[程序]
{$I-}{输入的数据为整数}
programThreebit;
varx,n,a,b,c:
INTEGER;
BEGINwrite('
Input3bitnaturedata:
'
);
readln(n);
IF(n>
99)and(n<
1000)then
begina:
=nDIV100;
{求百位数}
b:
=(n-a*100)DIV10;
{求十位数}
c:
=nmod10;
{求个位数}
x:
=c*100+b*10+a;
{得新数X}
writeln('
Number='
x:
3);
end
ELSEwriteln('
Inputerror!
END.
2、求三角形面积:
给出三角形的三个边长为a,b,c,求三角形的面积。
提示:
根据海伦公式来计算三角形的面积:
S=
;
Area=
[解]1.输入的三角形三边长a,b,c要满足“任意两边长的和大于第三边长”。
2.按海伦公式计算:
s=(a+b+c)/2;
x=s*(s-a)*(s-b)*(s-c)这时若x>
=0,则求面积:
area=
,并输出area的值。
[程序]PROGRAMhl;
VARa,b,c,s,x,area:
real;
Inputa,b,c:
readln(a,b,c);
If(a>
0)and(b>
0)and(c>
0)and(a+b>
c)and(a+c>
b)and(b+c>
a)Then
Begins:
=(a+b+c)/2;
=s*(s-a)*(s-b)*(s-c);
Ifx>
=0ThenBeginArea:
=SQRT(x);
writeln('
Area='
area:
8:
End;
End
Elsewriteln('
)
END.
3、模拟计算器:
试编写一个根据用户键入的两个操作数和一个运算符,由计算机输出运算结果的程序。
这里只考虑加(+)、减(-)、乘(*)、除(/)四种运算。
例1:
Inputx,y:
153
Inputoperator(+,-,*,/):
+
15.00+3.00=18.00
例2:
50
/
divideiszero!
[解]该题关键是判断输入的两数是作何种运算(由输入的运算符operator决定,如'
+'
、'
-'
*'
/'
分别表示加、减、乘、除法的运算)。
其中要进行除(/)运算时,要先进行合法性检查,即除数不能为0。
[程序]
PROGRAMOper;
Varx,y,n:
operator:
char;
Begin
write('
Inputx,y:
readln(x,y);
Inputoperator:
readln(operator);
Caseoperatorof
'
:
n:
=x+y;
{加法运算}
=x-y;
{减法运算}
=x*y;
{乘法运算}
Ify=0then{除法运算}
beginwriteln('
Divideiszero!
halt;
end
Elsen:
=x/y;
elsebeginwriteln('
Inputoperatorerror!
end;
writeln(x:
6:
2,operator,y:
2,'
='
n:
2);
End.
4、念数字:
编一个“念数字”的程序,它能让计算机完成以下工作:
当你输入一个0至99之间的数后,计算机就会用汉字拼音印出这个数的念结束。
例1:
Inputdata:
35SANSHIWU
LING
如果输入的数不在0到99之间,就印出“CUOLE”(错了),请求重新输入。
注:
为了使不熟悉汉语拼音的同学也能做这个题,把“零,一,二,三,……,九,十”的拼音法写在下面。
零LING一YI二ER三SAN四SHI五WU
六LIU七QI八BA九JIU十SHI
[解]输入数在0~99之间,若x为两位数则拆分为十位数、个位数。
然后调用念
数过程Readdigit用汉字拼音印出各位数(0~9)的念。
{$I-}
ProgramNinShu;
Varx,a,b:
Integer;
ProcedureReadDigit(n:
Integer);
{念数过程:
n=0~9}
Casenof
0:
write('
LING'
1:
YI'
2:
ER'
3:
SAN'
4:
SHI'
5:
WU'
6:
LIU'
7:
QI'
8:
BA'
9:
JIU'
End;
{ReadDigit}
Begin{main}
Repeatwrite('
readln(x);
if(x<
0)or(x>
99)thenwriteln('
CuoLe'
Until(x>
=0)and(x<
=99);
If(x>
=9)thenReadDigit(x){调用念数过程}
ElseBegina:
=xDIV10;
=xmod10;
{位数拆分}
Ifa<
>
1thenReadDigit(b);
Shi'
ifb<
0thenReadDigit(b);
writeln;
5、数列找数:
数组A(N)的各下标变量中N个互不相等的数,键盘输入正整数M(M≤N),要求打印数组中第M大的下标变量的值。
例如:
数组A(10)的数据为:
A
(1)
A
(2)
A(3)
A(4)
A(5)
A(6)
A(7)
A(8)
A(9)
A(10)
16
57
20
19
38
41
6
13
25
32
运行结果:
INPUTANNUMBER:
3A(5)=38(即第3大的数是A(5)=38)[解]该题要从N个互不相等的数中找第M大的值。
有以下两种解法:
解法一:
初始时:
A数组存放N个互不相等的数;
B数组用于存放数组A的下标。
见下表一。
下标值i
1
2
3
4
5
7
8
9
10
数组A
数组B
降序处理(冒泡排序法):
数组A的元素由大到小进行排序,同时数组B的元素排列也随之变化。
下标值I
数组B(原数组A的下标)
例题中M=3,由表二知A[3]=38,B[3]=B[M]=5(原数组A的下标值)即为所求。
[程序]ProgramMax01;
{冒泡排序法}vari,j,n,m,x:
A,B:
ARRAY[1..100]ofinteger;
ProcedureInit;
{读数初始化过程}Vari,j:
fd:
boolean;
Begin
InputN:
readln(N);
{读入N}ifN<
1thenbeginwriteln('
Input'
N:
3,'
Data:
Fori:
=1tonDo
beginread(A[i]);
B[i]:
{读入A[i],且B[i]初值置为i}
Readln;
i:
=1;
=false;
{数组中的数有相同的标志}whileNOTfdand(i<
=N-1)doBeginj:
=i+1;
WhileNOTfdand(j<
=N)do
beginfd:
=A[i]=A[j];
{若A[i]=A[j],则fd=true;
否则fd=false}
j:
=j+1;
Iffdthen{fd为True,则表示数组中至少有两个相等的数}
Moreequalnumber!
InputM:
readln(M);
IfM>
Nthen{表明所找的数M已超过输入数的总数N}
{Init}
Begin{MAIN}Init;
{读数过程}
fori:
=1toN-1do{冒泡排序}forj:
=i+1toNdoifA[i]<
A[j]thenbeginx:
=A[i];
A[i]:
=A[j];
A[j]:
=x;
{交换A[i]与A[j]的值}x:
=B[i];
=B[j];
B[j]:
{交换B[i]与B[j]的值}
A('
B[M],'
)='
A[M]);
{输出第M大的数、原下标值}
解法二(搜索法):
用B[i]表示在A[1]、A[2]、A[3]、……、A[N]中比A[i]大的个数(i=1,2,3,……,N)。
搜索的结果见下表三:
A数组
B数组
6
例题中M=3,由表三知B[5]=3=M,A[5]=38即为所求。
[程序]Vari,j,k,m,n:
{具体程序见解法一}Begin{MAIN}
Init;
{读数过程}
=1tondo
beginB[i]:
{B[i]初始值为1,即假定所有A[i]都可能为最大数}
forj:
if(i<
j)and(A[i]<
A[j])thenB[i]:
=B[i]+1;
ifB[i]=Mthenk:
k,'
A[k]);
在上述表三中,我们可以发现:
例中M=3,在搜索过程中当下标i=5时,B[5]=M=3,此时已找到所求,即A[5]=38。
这样i>
5时就不用再搜索下去。
因此,可对解法二的算法优化如下:
1.读数至A数组
2.i=1;
fd=false;
{fd:
判断是否已找到所求数的标志}
3.当(fd=false)and(I<
=n)时,做
(1)B[i]=1{表示数列中比A[i]小的数的总个数+1,初始值为1}
(2)j=1
(3)当j<
=n时,做
①如果(i<
j)and(A[i]<
A[j]),则B[i]的值加1。
②j=j+1
(4)如果B[i]=M,则输出所求:
A[i],且fd=true。
(5)i=i+1
4.程序结束。
[主程序]
Begin{MAIN}
{读数过程}
fd:
{找到所求解的标志值}
whilenotfdand(i<
{B[i]初始值为1,即假定所有的A[i]都可能为最大的数}
whilej<
=ndo
begin
{whilej}
ifB[i]=Mthen{找到所求便输出,并退出比较}
i,'
A[i]);
=true;
{whilei}
6、数制转换:
编程输入十进制N(N:
-32767~32767),请输出它对应的二
进制、八进制、十六进制数。
INPUTN(-32767~32767):
222
222TURNINTO2:
11011110
222TURNINTO8:
336
222TURNINTO16:
DE
[解]十进制数转化为某进制数的转换方法,如下图示:
除x逆序取余法
十进制数x进制数(x=2,8,16等)
例中n=222(十进制数),转换成x进制数的过程如下图示:
(1)十进制数→二进制数
(2)十进制数→八进制数(3)十进制数→十六进制数
x=2222被除数(最大商)x=82226x=16222E…(14)10
21110低位82731613D…(13)10
2501逆8330
2250余序0
2120数取
260余
231数
211高位
0(最大商为0时停止)
将每次所得的余数由下至上排列(逆序取余数),即有:
(222)10转换成二进制数得到:
1100010
(222)10转换成八进制数得到:
(222)10转换成十六进制数得到:
13、14
这时得到的逆序余数串(在数组B[1]、B[2]、……、B[k]中)的每位数均为十进制数。
程序中利用字符串A来计算x进制数的位数(即COPY(A,B[i]+1,1)),见下表:
数组B
0
2
3
4
5
6
7
8
10
11
12
13
14
15
字串A
A
B
C
D
E
F
下标i
9
16
由上表得:
(222)10=(1100010)2=(336)8=(DE)16
Programjj;
varN,k:
B:
array[1..1000]ofinteger;
Procedurechg10(N,x:
integer);
{将十进制数N转换成x进制数}
Begink:
=0;
{转换后的x进制数位的长度}
whileN<
0do{N不为0时}
beginB[k]:
=Nmodx;
{除以x取余数}
N:
=NDivx;
{取最大商N}
k:
=k+1;
{x进制数位加1}
{chg10}
ProcedureSput(N,x:
{进制数输出}
VARi:
A:
string;
BeginA:
0123456789ABCDEF'
;
{表示x进制数的位数串}
write(N:
6,'
Turninto'
=k-1downto0dowrite(copy(A,B[i]+1,1));
{逆序输出x进制数}
{Sput}
begin{MAIN}
InputN(-32767to32767):
if(N<
=-32767)or(N>
32767)then
chg10(N,2);
Sput(N,2);
{十进制数转换成2进制数,并输出}
chg10(N,8);
Sput(N,8);
{十进制数转换成8进制数,并输出}
chg10(N,16);
Sput(N,16);
{十进制数转换成16进制数,并输出}
end._
编程入门题
(二)
1、求素数:
求2至N(2≤N≤500)之间的素数。
输入:
N=100
输出:
23571113
171923293137
414347535961
717379838997
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.程序结束
programexa;
usescrt;
vari,k,n,w,t:
in