Python算法100例-2.3 求车速

完整源代码项目地址,关注博主私信'源代码'后可获取

1.问题描述

一辆以固定速度行驶的汽车,司机在上午10点看到里程表上的读数是一个对称数(即这个数从左向右读和从右向左读是完全一样的),为95859。两小时后里程表上出现了一个新的对称数,该数仍为5位数。问该车的速度是多少?新的对称数是多少?

2.问题分析

根据题意,司机在上午10点看到里程表上的读数是一个对称数95859,两小时后里程表上出现的新的对称数必然大于95859。因此,假设所求对称数为i,并设其初值为95860,即从95860开始检测,使i的取值依次递增。

对于i的每一次取值都将其进行分解,然后将对称位置上的数字进行比较,即第1位和第5位比较,第2位和第4位比较。如果每个处于对称位置上的数都是相等的,则可以判断出当前的i中所存放的5位数即为里程表上新出现的对称数。

3.算法设计

根据问题分析可知,i需要从95860开始试探,因此显然需要使用循环结构。在循环体中完成分解5位数并保存、再检测是否为对称数的功能。

根据问题分析可知,需要对一个5位数进行分解并保存,因此可以使用数组来保存分解后生成的5个数字。这样,在进行对称位置上的数字比较时,实际上进行的是指定下标的数组元素的比较。

4.确定程序框架

由上述分析可知,程序的主体是一个循环结构。

(1)循环试探

使用for语句进行循环试探,代码如下:

# 以95860为初值,循环试探
# i为里程数初始值,因最后结果仍是5位数,故最大值为100000
for i in range(95860, 100000):
   # 循环体语句

根据题意表述,两小时后里程表上出现了一个新的对称数,该数仍为5位数,故最大的循环次数是100000,而起始里程数是95860。

(2)分解5位数并保存

对当前变量i中存放的5位数进行分解,并将结果保存在数组a中。第1次分解出“万”位上的数字,存放在数组元素a[0]中;第2次分解出“千”位上的数字,存放在数组元素a[1]中;接着依次分解出“百”“十”“个”位上的数字,分别存放在数组元素a[2]、a[3]和a[4]中。代码如下:
# 从高到低分解当前i中保存的5位数,并顺次存放在数组元素a[0]~a[4]中
t = 0                          # 列表a的下标
k = 100000
while k >= 10:
    a[t] = (i % k)//(k // 10)  # 保存分解后的数字
    k /= 10
    t += 1

(3)判断是否为对称数

分解出的5个数字按照从低位到高位的顺序分别保存在数组元素a[0]~a[4]中。因此,判断该5位数是否为对称数的条件为:a[0]==a[4] and a[1]==a[3]是否成立。

if a[0] == a[4] and a[1] == a[3]:
    print("里程表上出现的新的对称数为:%d%d%d%d%d" %(a[0],a[1],a[2],a[3],a[4]))
    print("该车的速度为:%.2f" %((i-95859)/2.0))
    break                 # 跳出循环

上面的if语句中使用了break语句来跳出循环试探过程,即一旦找到一个对称的5位数,则立即跳出循环,这保证了经过有限次循环后程序可以正常结束。

程序流程图如图所示。

在这里插入图片描述

5.完整的程序

根据上面的分析,编写程序如下:

%%time
# 求车速
if __name__=="__main__":
    a = [0, 0, 0, 0, 0]                             # 列表a用来存放分解后的5个数字
    # i为里程数初始值,因最后结果仍是5位数,故最大值为100000
    for i in range(95860, 100000):
        # 从高到低分解当前i中保存的5位数,并顺次存放在数组元素a[0]~a[4]中
        t = 0                                                       # 列表a的下标
        k = 100000
        while k >= 10:
            a[t] = (i % k)//(k // 10)       # 保存分解后的数字
            k /= 10
            t += 1
        if a[0] == a[4] and a[1] == a[3]:
            print("里程表上出现的新的对称数为:%d%d%d%d%d" %(a[0],a[1],a[2],a[3],a[4]))
            print("该车的速度为:%.2f" %((i-95859)/2.0))
            break                                           # 跳出循环


里程表上出现的新的对称数为:95959
该车的速度为:50.00
CPU times: user 436 µs, sys: 17 µs, total: 453 µs
Wall time: 449 µs

6.问题拓展

该程序的主体是一个循环结构,使用了for语句进行循环试探,i是循环变量,初值为95860,代码如下:

# 以95860为初值,循环试探
# i为里程数初始值,因最后结果仍是5位数,故最大值为100000
for i in range(95860, 100000):
   # 循环体语句

也可以使用while循环结构来替代上面的for循环。在进入while循环前要先设置i的初值为95860,while循环的条件为永真,因此,在循环体中要有退出循环的条件。完整的代码如下:

%%time
# 求车速

if __name__=="__main__":
    a = [0, 0, 0, 0, 0]                                     # 列表a用来存放分解后的5个数字
    i = 95860                                                               # i为里程数初始值
    while 1:
        # 从高到低分解当前i中保存的5位数,并顺次存放在数组元素a[0]~a[4]中
        t = 0                                                               # 列表a的下标
        k = 100000
        while k >= 10:
            a[t] = (i % k)//(k // 10)               # 保存分解后的数字
            k /= 10
            t += 1
        if a[0] == a[4] and a[1] == a[3]:
            print("里程表上出现的新的对称数为:%d%d%d%d%d" %(a[0],a[1],a[2],a[3],a[4]))
            print("该车的速度为:%.2f" %((i-95859)/2.0))
            break                                                   # 跳出循环
        i += 1
里程表上出现的新的对称数为:95959
该车的速度为:50.00
CPU times: user 474 µs, sys: 0 ns, total: 474 µs
Wall time: 479 µs

从上面的代码中可以看到,除了将for循环改为while循环以外,循环体中的语句没有变化,当找到新的对称数以后,就可以使用break语句跳出while循环了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飘逸高铁侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值