内容正文:
63
第四章 常用算法与实例
一、枚举算法
1枚举算法的基本概念
枚举算法:根据所需解决问题的条件,在给定的范围内给出该问题所有可能的解,把解全
部列举出来,并逐个检验出问题真正解的方法,枚举法也称为穷举法.
2枚举算法的实现方式
(1)确定范围:确定问题所涉及的情况有哪些,列举出所有可能的情况,不能重复,也不能
遗漏.
(2)验证条件:这些情况需要满足什么条件才能成为问题的解答,通常是在循环和分支组
合结构中,过滤掉不符合条件的解,保留符合条件的解.
例4G1 一张单据上有一个五位数的编号,万位数是1,千位数是4,十位数是7,个位数是
3,百位数已经模糊不清,只知道该五位数是57或67的倍数,找出所有满足这些条件的五位数
并输出.如图4G1所示,把流程图填写完整( ).
64
图4G1
k=0
whilek<10:
n=14073+k∗100
ifn%57==0orn%67==0:
print(n)
k=k+1
分析与解答:牧举算法要列举所有的可能条件,不能重复,不能遗漏.五位数上百位模糊
不清,根据流程图提示信息k∗100,所以k的取值范围是0~9,而且此五位数是57或67的倍
数,所以第一空填为n%57==0orn%67==0,循环需要继续下去,所以第二空是k=
k+1.即答案是n%57==0orn%67==0,k=k+1.
例4G2 素数,也叫质数.判断一个数是否为素数,可以根据素数的定义,只能被1和它自
己本身整除,即一个素数除了它本身以外,不可能分解为其他自然数的乘积.找出2~1000里
面所有的素数,请将流程图4G2空白横线处填写完整( ).
图4G2
importmath
i=2
whilei<=1000:
p=True
j=int(math.sqrt(i))+1
forkinrange(2,j):
ifi%k==0:
p=False
break
ifp==True:
print(i,"isaprimenumber")
else:
print(i,"isnotaprimenumber")
i=i+1
65
分析与解答:判断素数需要用到二重循环,外层循环设置变量i从2~1000,这层循环的作
用就是枚举所有可能的解不重复不遗漏.内层循环作用判断i是否是素数,开始默认i为素
数,若i能被k整除,则说明i不是素数,退出循环;设置布尔变量p置初始值为true,用来记录
i是否能被k整除,若循环遍历中i被k整除了,则置p为false;最后用布尔变量p的值来判断
输出i的素数情况,若2~sqrt(i)都不能整除,p值还是为true,没有被改变,则输出i是素数,
否则输出i不是素数.即答案是i%k==0,p== True.
二、排序
1排序概念
把杂乱无章的数据变为有序的数据,这一过程称为排序.排序有升序和降序两种:升序,
即由小到大排列;降序,即大到小排列.
2冒泡排序的基本思想
第一轮操作,将待排序的n个数据存到列表中,从第一个元素开始,比较a[l]和a[2],若
a[l]>a[2]成立,则交换a[l]和a[2],然后以同样的方法比较a[2]和a[3]a[n-1]和a[n],
经过n-l次比较和交换后,列表a中最大值被排出.
第二轮操作,还是从第一个元素开始,依次比较到a[1]和a[2]直到a[n-l],比上一轮操
作少一次比较.第二轮操作的结果是余下的n-1个数据的最大值被排出.
每一轮操作都比上一轮操作少一次比较,一共要经过n-1轮操作,最后列表a中的元素
就按升序排列好了.如果要采用降序排列,只需要把大于交换方式修改为小于交换即可.
冒泡排序的实现是通过二重循环,外循环是控制第几轮操作,内循环是控制本轮操作中相
邻数的比较和交换.
例1 对列表B采用冒泡排序方法排序见图4G3.
图4G3
66
3选择排序的基本思想
首先找到列表中最小(最大)的那个元素;其次将它与列表中的第一个元素交换位置;接着
在剩余的元素中找到最小(最大)的元素,将它与列表中的第二个元素交换位置;如此往复,直
到完成所有的数据排序.
例2 对列表B采用选择排序方法排序见图4G4.
图4G4
例4G3 对一列数据[40、7、37、27、18、63、49、15]按升序排列,使用冒泡排序方法,第一、二
轮需进行相邻列表元素交换的次数一共为( ).
A.4次 B.5次 C.9次 D.7次
分析与解答:冒泡排序升序排列基本思想,从一列数据的第一个元素开始依次和相邻的元
素进行比较,若前面元素比后面元素大,就交换这两个元素.以上8个数据存放在列表a中,
如下详解8个元素的比较和交换过程:
第1次比较,a[l]>a[2]成立,需交换 7、40、37、27、18、63、49、15
第2次比较,a[2]>a[3]成立,需交换 7、37、40、27、18、63、49、15
第3次比较,a[3]>a[4]成立,需交换 7、37、27、40、18、63、49、15
第4次比较,a[4]>a[5]成立,需交换 7、37、27、18、40、63、49、15
第5次比较,a[5]>a[6]不成立,不需交换 7、37、27、18、40、63、49、15
第6次比较,a[6]>a[7]成立,需交换 7、37、27、18、40、49、63、15
第7次比较,a[7]>a[8]成立,需交换 7、37、27、18、40、49、15、63
由上详解过程可知共进行了6次交换,完成第一轮操作.
第1次比较,a[l]>a[2]不成立,不需交换 7、37、27、18、40、49、15、63
第2次比较,a[2]>a[3]成立,需交换 7、27、37、18、40、49、15、63
第3次比较,a[3]>a[4]成立,需交换 7、27、18、37、40、49、15、63
67
第4次比较,a[4]>a[5]不成立,不需交换 7、27、18、37、40、49、15、63
第5次比较,a[5]>a[6]不成立,不需交换 7、27、18、37、40、49、15、63
第6次比较,a[6]>a[7]成立,需交换 7、27、18、37、40、15、49、63
由上详解过程可知共进行了3次交换,完成第二轮操作.即答案是C.
例4G4 对一列数据[38、9、65、14、16、52、67、15],若采用选择排序算法对其进行从小到大
排序,则需要( )轮交换完成排序.
A.4 B.5 C.6 D.7
表4G1
38 9 65 14 16 52 67 15
第一轮排序 9 38 65 14 16 52 67 15
第二轮排序 9 14 65 38 16 52 67 15
第三轮排序 9 14 15 38 16 52 67 65
第四轮排序 9 14 15 16 38 52 67 65
第五轮排序 9 14 15 16 38 52 65 67
分析与解答:选择排序升序排列的基本思想是在一列数据中选出最小的元素,把它与第一
个元素交换,然后在剩下的元素中再选出最小的元素与第二个数据交换,依此循环,直至所有
元素按照从小到大的排序完成.即答案是B.
三、查找
1查找的概念
查找是生活中最常见的查询数据或者信息的技术,即通过一定的方法找出与给定关键字
相同的数据元素的过程.
2顺序查找的基本思想
顺序查找是一种最基本、最简单的查找算法.即从列表的第一个元素开始,按列表元素的
顺序逐个将列表元素值与给定的值进行比较,若某个列表元素值和给定值相等,则查找成功,
找到所查数据的位置;反之,查找不成功.
3对分查找的基本思想
对分查找也称为二分查找,其基本思想是在有序的数据序列中,首先将要查找的数据与有
序列表内处于中间位置的列表元素进行比较,如果两者相等,则查找成功;否则根据列表元素
的有序性,就可确定该数据应该在列表的前半部分还是在后半部分继续进行查找;在新确定的
范围内,继续按上述方法进行查找,直至找到要查找的数据,则查找成功;或查到列表中不存
在,则查找不成功.
对分查找的条件是被查找的列表中的元素必须是有序的.
68
4顺序查找与对分查找效率比较
查找算法的效率取决于查找的次数,顺序查找的次数由所查找的元素在序列中的位置所
决定.而对分查找的效率要高得多,但是对分查找必须基于有序排列的数据.因此,针对查找
规模较小的无序数据,顺序查找也是一种常用的有效方法.
例3 用Python程序实现,使用对分查找,在有序列表中查找目标元素.
List=[1,3,5,7,9,11,13,15,16,18]
target=8
first=0
n=len(list)
last=n-1
whilefirst<=last:
mid=(first+last)//2
iflist[mid]==target:
print(list[mid])
break
eliflist[mid]>target:
last=mid-1
else:
first=mid+1
iflist[mid]!=target:
print(“cannotfindthetargetnumber”)
例4G5 用对分查找法从列表[2、4、6、8、15、16、27、33、55]中找到数据16的最少查找次数
是( )次.
A.2 B.3 C.4 D.6
分析与解答:这里共有9个数,依次序号为1~9,第一次中间处第5号为15,查找目标16
大于第5号数据15,所以确定在列表的后半部分查找,范围是6~9;第二次新范围中间处第7
号为27,查找目标16小于第7号数据27,最终缩小查找范围为6~6;第三次中间处第6号为
16,查找目标16等于第6号数据16,所以查找次数为3次.即答案是B.
例4G6 (上海市信息科技学业水平考试题)下面是一组有序的列表,现进行对分查找,查
找joe所访问的过程是( ).
69
1 2 3 4 5 6 7 8 9 10 11 12 13 14
al bee car dad eye for get hen ink joe kea leo mar pig
A.get kea ink joe B. get car kea joe
C.get kea hen joe D. get hen kea joe
分析与解答:本题主要考查对分查找,列表中共有14个元素,第一次找到中间位置7号元
素get,确定目标元素joe在列表的后半部分即8号到14号元素;继续对分查找,第二次在新范
围内找到中间位置11号元素kea,确定目标元素joe在kea的前半部分,即列表新确定范围8
号到10号元素;第三次使用对分查找,找到8号元素到10号元素中间元素ink,不是目标元素
joe;最后范围缩小到只剩下10号元素joe,查找成功,如果列表中没有元素joe,则查找不成功.
即答案是 A.
例4G7 关于对分查找和顺序查找算法的叙述中,正确的是( ).
A.顺序查找需要排序,效率低;对分查找不需要排序,效率髙
B.顺序查找不需要排序,效率低;对分查找需要排序,效率高
C.顺序查找不需要排序,效率高;对分查找需要排序,效率低
D.顺序查找需要排序,效率高;对分查找不需要排序,效率低
分析与解答:本题主要考查对分查找与顺序查找效率问题.顺序查找的次数由所查找的
元素在序列中的位置所决定,顺序查找之前不需要对数据进行排序,仅仅适合小规模的数据查
找,效率低.对分查找是一种效率很高的查找方法,但被查找的数据必须是有序的.即答案
是B.
1小明玩猜价格游戏,价格的范围是10元到170元.他第一次猜90元,低了;第二次猜130
元,高了;第三次猜110元,又低了;第四次他猜120元小明在猜价格时采用的方法是
( ).
A.二分法 B.排序法 C.顺序法 D.随机法
2对于有序的数据序列,可以使用的查找算法有( ).
A.顺序查找 B.对分查找 C.两者都是 D.两者都不是
3图书管理系统对图书管理是按图书的序号从小到大进行管理的,若要查找一本已知序号的
书,则能快速地查找到的算法是( ).
A.枚举算法 B.选择排序 C.对分查找 D.冒泡排序
70
4已知在8个大小相同的小球中,有一个是废品球,废品球的重量比正品球轻.现有一台无
砝码的天平,试用二分查找算法,至少要称( )次才能找出废品球.
A.3 B.4 C.5 D.7
5关于对分查找和顺序查找算法的叙述,正确的是( ).
A.对分查找之前需要对数据进行排序,查找过程效率较低
B.顺序查找之前不需要对数据进行排序,查找过程效率较低
C.顺序查找之前需要对数据进行排序,查找过程效率较高
D.对分查找之前不需要对数据进行排序,查找过程效率较高
6使用选择排序对一列数据[11、8、36、25、60]按升序排列,共需要几次列表元素之间的交换
( ).
A.2次 B.3次 C.4次 D.5次
7对于列表[2、5、6、8、10、12、13、16、17],分别用顺序查找和对分查找的方法在其中找数据8
的最少次数是( ).
A.1、3 B.1、4 C.4、3 D.4、4
8列表d中的数据存放情况如表4G2所示,则流程图4G5实现的功能是( ).
图4G5
表4G2
d[1] d[2] d[3] d[4] d[5] d[6]
12 45 23 18 6 10
A.在列表d中顺序查找18,找遍所有数据后,找到的则输出“win”,否则输出“lose”
B.在列表d中顺序查找18,一旦找到,则停止查找并输出“win”
C.在列表d中顺序查找18,找遍所有数据后,输出“lose”
D.在列表d中顺序查找18,一旦找到,则继续直至查找结束并输出“win”
71
9列表a中存放了字符串,存放情况如下表4G4所示,现对列表a进行查找操作,以下表述中
正确的是( ).
表4G4
a[1] a[2] a[3] a[4] a[5] a[6] a[7]
cake fish meat pear rice soup wolf
A.用顺序方式查找“pear”,需要比较4次才能找到
B.由于列表a中没有“pizza”,所以无法进行对分查找
C.用顺序方式查找“cake”,比较1次就能找到;而用对分方式,比较3次才能找到,所以可
以得出顺序查找一定比对分查找效率高的结论
D.用对分方式查找“rice”,依次被比较的字符串为“Pear”和“rice”
10要在以下两列表中(见表4G5)进行数据查找,下列选项中查找方法使用错误的是( ).
表4G5
a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a[10]
88 85 76 61 55 49 46 32 21 12
b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8] b[9] b[10]
54 31 43 12 3 6 56 87 90 100
A.列表a可以直接使用顺序查找 B.列表b可以直接使用对分查找
C.列表a可以直接使用对分查找 D.列表b可以直接使用顺序查找
11现有8位同学的身高数据如列表[155、165、168、172、175、178、180、185],若用对分查找算
法查找数值155,则依次被访问到的数据是( ).
A.155 B.168、155 C.172、165、155 D.175、165、155
12列表顺序列出了7个同学的身髙(单位:厘米)(见表4G6),若用对分查找算法查找数值
168,则依次被访问到的数据是( ).
表4G6
188 177 175 172 168 166 155
A.172、155、158 B.172、166、168 C.188、155、168 D.155、166、168
13表4G7列出了存放在列表d中的8个学生的考试成绩,若用选择排序算法升序排列,在第
三遍加工结束后,列表变量d[8]的值应该为 ,总共需要做 遍加工.
表4G7
d[1] d[2] d[3] d[4] d[5] d[6] d[7] d[8]
90 80 85 73 72 71 66 70
14若一个三位数x=100a+10b+c(a、b、c都是个位数),满足a3+ b3+c3=x,则x称为
水仙花数,找出所有的水仙花数.图4G6空白处填入合适表达式为 ,并完成
Python编码.
72
图4G6
15幼儿园欲购买40块三种不同品种的巧克力,价格分别为3元、2元和1元.每种巧克力都
买到,预算100元,怎么样才能正好把这些钱用完? 图4G7空白处填入合适表达式为
,并完成Python编码.
图4G7
73
16已知四位数3025有一个特殊的性质:它的前两位数30和后两位数25的和是55,而55的
平方正好等于3025.如图4G8所示,找出所有满足条件的四位数的算法,空白处填入合适
表达式为 ,并完成Python编码.
图4G8
17一张票据上有一个五位数的票号,万位数是2,千位数是3,十位数是5,个位数和百位数已
经模糊不清.该五位数是37和47的倍数,找出所有满足条件的五位数并输出.图4G9空
白处填入合适表达式为 ,并完成Python编码.
图4G9
74
18用5到9这五个数字,组成两位数,在组成的数中不能有重复的数字.共可以组成多少组
数并输出所有符合条件的两位数,图4G10空白处填入合适表达式为 ,并完成PyG
thon编码.
图4G10
19用0、2、4、6、8这五个数字,组成两位数,数字可以重复使用,但个位数不能是6.共可以组
成多少组数并输出所有可能的两位数,图4G11空白处填入合适表达式为 ,并完成
Python编码.
图4G11
75
20小明同学去邮局欲将一张面值为100元的邮票等值换成5元、1元的小面值邮票共40张,
要求每种邮票不少于1张,问5元和1元面值的邮票各多少张? 编写 Python程序实现
功能.
21编写Python程序,该程序要实现的功能如下:一个n位正整数,如果它每一位上数字的n
次幂的和等于它本身,就称该数为自幂数.当n=4时,这个四位的自幂数也称为四叶玫
瑰数,例如:1634=14+64+34+44,输出并统计2000~9000内所有的玫瑰数.
22编写Python程序,该程序要实现的功能如下:求所有五位数中满足能被17整除且十位数
字为5的数之总数.
76
23编写Python程序,该程序要实现的功能如下:一个六位正整数x能同时被157和233整
除,且第一位和最后一位的数字恰好相同.
24编写Python程序,该程序要实现的功能如下:求首尾两个数字相同的四位数中能被3除
余2的所有五位数之和.
25编写Python程序,该程序要实现的功能如下:有一个整数,它加上100后是一个完全平方
数,再加上168仍是一个完全平方数,请问该数是多少?
154
15s=0
n=int(input("pleaseinputanumber:"))
foriinrange(101,n+1):
s=s+10/i
print(s)
16n=int(input(“pleaseinputanumber:”))
s=0
t=0
foriinrange(1,n):
t=t+i
s=s+i/t
print(s)
17s=0
forxinrange(100,1000):
P1=int(x/100)
P2=int(x/10)%10
P3=x%10
ifP1<P2andP2< P3:
s=s+1
print(s)
第四章 常用算法与实例
巩固练习
1A 2.C 3.C 4.A 5.B 6.A 7.C 8.B 9.A 10.B 11.C 12.B 13.80/6
14x=100
a∗∗3+b∗∗3+c∗∗3==x
完整Python程序:
x=100
whilex<=999:
a=int(x/100)
b=int((x%100)/10)
c=int(x%100)
ifa∗∗3+b∗∗3+c∗∗3==x:
155
print(x)
x=x+1
15s==100andk>0
i=i+1
完整Python程序:
i=1
whilei<=33:
n=1
whilen<=40:
k=40-i-n
s=i∗3+n∗2+k
ifs==100andk>0:
print(i,n,k)
n=n+1
i=i+1
16int(n/100)
n==c∗c
完整Python程序:
n=1000
whilen<=9999:
a=int(n/100)
b=n%100
c=a+b
ifn==c∗c:
print(n)
n=n+1
17n%37==0andn%47==0
k=k+100
完整Python程序:
i=1
whilei<10:
k=100
whilek<1000:
156
n=23050+i+k
ifn%37==0andn%47==0:
print(n)
k=k+100
i=i+1
18n=5
n!=i
完整Python程序:
k=0
i=5
whilei<=9:
n=5
whilen<=9:
ifn!=i:
print(n)
k=k+1
n=n+1
i=i+1
print(k)
19k=0
k!=6
完整Python程序:
i=2
whilei<=8:
k=0
whilek<=8:
ifk!=6:
print(i∗10+k)
k=k+2
i=i+2
20forxinrange(1,20):
y=40-x
if5∗x+y==100:
print(x,y)
157
21x=0
foriinrange(2000,9000):
if(i//1000)∗∗4+(i//100%10)∗∗4+(i%100//10)∗∗4+(i%10)∗∗4==i:
print(i)
x=x+1
22s=0
foriinrange(10000,100000):
ifi%17==0andi//10%10==5:
s=s+1
print(s)
23foriinrange(100000,1000000):
ifint(i/100000)==i%10andi%157==0andi%233==0:
print(i)
24s=0
forninrange(1000,10000):
a=n%10
b=n//1000
ifa==bandn%3==2:
s=s+n
print(s)
25importmath
num=1
whileTrue:
ifmath.sqrt(num+100)-int(math.sqrt(num+100))==0and\
math.sqrt(num+268)-int(math.sqrt(num+268))==0:
print(num)
break
num=num+1
(注:“\”续行符)
第五章 人工智能与信息社会
巩固练习
1D 2.A 3.B 4.A 5.D 6.C 7.A 8.A 9.A 10.B
11D 12.A 13.B 14.A 15.B 16.C 17.B 18.C 19.A 20.B
21C 22.B 23.A 24.C 25.C 26.B 27.D 28.D 29.B 30.B