查看: 287|回复: 1

[讨论交流] [Python]2019网络夏令营之腾讯编程营练习题解答(下)

[复制链接]
本帖最后由 szjuliet 于 2019-10-14 23:20 编辑

2019网络夏令营之腾讯编程营练习题解答(上)(练习中的5个任务)
2019网络夏令营之腾讯编程营练习题解答(下)(练习中另外3个任务)


题目6:分数统计
小扣叮帮老师统计班级的考试情况,需要得到全班某学科的总分,及平均分。

输入描述
第一行,整数 N,表示班级的学生人数;
接下来的 N 行,每行一个数字,代表每个同学的得分


输入例子
6
95
93
81
79
98
63


输出描述
两个用空格分隔的数字,前一个是总分,后一个是班级平均分(保留2位小数)

每行输出以换行符 \n 结束。(Python 的 print 语句自带换行符;C/C++ 请使用 "<< endl" 换行)


输出例子
509 84.83

思路:这道题很简单,求和和求平均,只是输出的时候要格式化输出。
[Python] 纯文本查看 复制代码
s = 0

n = int(input())
for i in range(n):
    data = int(input())
    s += data #总分

print("{:d}".format(s), "{:.2f}".format(s/n)) #平均分保留小数点后面两位

201910053796.png


题目7:报数
小扣叮和同学一起玩抓迷藏的游戏,为了确定由谁来负责找人,大家决定用报数的方式。
所有的小朋友排成一队,随机选择一个数字,然后从前往后报数,到底后再往前报数,最后报到这个数的人就是选中的人。
比如四个小朋友分别是:A,B,C,D。数字为:8。则报数的顺序为:A1,B2,C3,D4,C5,B6,A7,B8。选中的人是:B。

输入描述
第一行为两个数字以空格分隔,第一个数字 N 为参加游戏的小朋友的人数,第二个数字 M 为报数的数目。
第二到第 N+1 行,每行为一个小朋友的名字。名字由 1 到 3 个大写英文字母(每个字母范围: A - Z)构成。


输入例子
4 8
A
B
C
D


输出描述
选中的小朋友的名字


输出例子
B



思路:这道题很有意思,看着挺简单,但是实现的方向却有很多种,有简有繁。可以引导学生充分讨论,找到最佳算法。
分析:因为要往返报数,从头到尾再从尾到头一共要报 1, 2, ..., n, n-1, ..., 3, 2个数,即 n + (n-2) (n>=2)。用列表表示就是[1, 2, 3, ..., n, n-1, n-2, ..., 3, 2]。报数为m,而报数的人的序数就是索引值为 (m mod (2*n-2) - 1 所对应的数字。
例如有5个数,生成列表为[A, B, C, D, E, D, C, B],一共8元素。如果报数为3,则 3 mod 8 -1 =2,报数为索引为2的数,即C,C报数;报数为10, (10 mod 8) -1,索引为1,对应的数是B,B报数;报数为15,(15 mod 8)-1=6,索引为6,值是C,C报数。
[Python] 纯文本查看 复制代码
n, m = [int(i) for i in input().split()]  #n是报数人数,报的数为m
nameList = []

for i in range(n):
    line = input()
    nameList.append(line) #将每个同学的名字添加到nameList中

posList = nameList[0:n] + nameList[n-2:0:-1] # 生成往返完整报数列表。前一项为列表索引第0~(n-1)个列表项,后一项为索引倒数第2个开始,到索引第2个结束。注意切片不包含end索引。

position = m % (2*n-2) - 1 #往返完整报数的列表长度为(2*n-2),报数m对长度取余数,得到的值-1就是报数同学的名字在名字列表中的索引值

print(posList[position])


201910057977.png


题目8:售卖计划
小叮当暑期在一家杂货店打工。店主粗心大意进了一批食品,其中部分食品的过期时间比较短。该商店还有一些店规:

1. 每天只能出售一件商品;
2. 在过期日之前售出的话,利润不变;在过期日当天售出,利润减半;过期日之后不能售出

小叮当要制定一份售卖计划,让利润最高。

输入描述
第一行一个整数 N,表示多少个商品
接下来 N 行(每行一个商品),两个整数(用一个空格分隔),表示每个商品的利润、剩余有效期天数(包含过期日,=0 表示已过期,=1 表示当天)

其中:1<= N,利润,时间 <=10000


输入例子
3
20 2
2 1
10 3


输出描述
输出一个整数(四舍五入),表示获得的最大收益


输出例子
30


思路:这道题难度标着两颗星,但是实际实现却不容易,中间走了不少弯路。本来想不用遍历的方法,试了多种算法都没有完全正确,说明算法在运行过程中遇到了例外情况。最后考虑使用递归。程序实际运行很快,也能得出正确的结果,但是在扣钉中测试时在有15和20个商品的情况下报错:Errors:程序执行错误,错误码:1003signal: killed异常关闭!可能触及资源限制,Cpu运行 1 秒,内存 100 MB。错误:signal: killed
201910143492.png

错误原因应该是递归及类占用资源过多导致进程被杀掉。下面是在Pycharm中的程序运行结果,输出最大值为275。
201910142255.png

另外还有一个特别坑的,题目要求是“四舍五入”,Python的四舍五入比较麻烦,在XXXX.5的情况,会向靠近的一方倾斜。简单的说就是整数前面是单数则入,整数前面是双数则舍,如rount(1.5)=2, round(2.5)=2。我们也可称之为四舍六入,所以为了结果输出正确的整数值,在最终结果+0.1后再使用round()函数。

[Python] 纯文本查看 复制代码
#定义商品类
class Goods:
    #初始化,传递两个参数:商品的价格和保质期
    def __init__(self, price, expire):
        self.price = price
        self.expire = expire

    #计算当前售卖日期下商品的价格,当售卖日期小于保质期时,价格为原价;等于保质期时,价格减半;小于保质期时,价格为0.
    def currentValue(self, iDay):
        currentPrice = 0
        if iDay < self.expire:
            currentPrice = self.price
        elif iDay == self.expire:
            currentPrice = self.price * 0.5
        return currentPrice

# 定义递归。
def maxPrice(sellDay, leftList):
    if not leftList: #如果剩下的商品列表leftList为空,返回0。这一步必须做,否则调用时会出现None Type的错误
        return 0
    
    #在剩余商品列表中,如果其保质期小于当前售卖日期,说明这个商品已经没有售卖价值,将其从商品列表中移出
    for goods in leftList:
        if goods.expire < sellDay:
            leftList.remove(goods)
    
    # 如果剩下的商品列表leftList为空,返回0,递归结束
    if not leftList:
        return 0
    else:
        maxValue = 0 #初始化某种商品价格最大值为0
        for goods in leftList:
            nextList = leftList[:] #下一次递归要传递的列表,是当前leftList列表中的所有元素
            nextList.remove(goods) # 递归返回后,如果goods在leftList中,将goods移除
            maxValue = max(maxValue, goods.currentValue(sellDay) + maxPrice(sellDay + 1, nextList)) #递归调用,此时要特别注意,列表需要用nextList,而不是leftList
        return maxValue #返回最大值

n = int(input()) #输入商品个数
goodsList = []  # 初始化商品列表,goodsList保存商品实例

# 类实例化,输入商品价格及保质期并保存到实例中
for i in range(n):
    # 实例化商品:商品价格及保质期
    price, day = [int(j) for j in input().split()]
    goodsList.append(Goods(price, day))
print(round(maxPrice(1, goodsList)+0.1)) #计算商品售卖总价值并四舍五入(python四舍六入)


3
20 2
2 1
10 3

201910145129.png


4
50 2
10 1
15 2
27 1

201910142503.png


7
20 1
2 1
10 3
100 2
8 2
5 20
50 10

201910144420.png

10
13 2
18 1
68 10
72 8
11 7
41 2
48 7
15 7
34 1
13 8

201910146951.png

15
3 12
65 1
61 3
60 2
86 1
10 8
12 5
20 7
30 6
40 9
52 3
25 5
32 3
18 6
15 4

程序运行中断,直接使用输出275可以看到最后结果是正确的。

201910144786.png

在IDLE中测试,结果为275:

201910148733.png

反思:个人感觉使用类和递归,程序易读,思路清晰。当然这种方法非常消耗系统资源,特别是当商品数量比较多时。



参考资料:https://blog.csdn.net/qq_39234705/article/details/82817703





爱玩编程的林爸爸  学徒

发表于 2019-10-22 14:08:45

收到了,正在学习中,非常感谢您的分享。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
wifi气象站

硬件清单

btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2019 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail