HNUCM-2022年秋季学期《算法分析与设计》练习13

w'w'w目录

问题 A: 1的个数

问题 B: 最小素数对

问题 C: 今年暑假不AC

问题 D: 隔离14天

问题 E: 月饼

问题 F: 汽车加油问题

问题 G: 战场的数目

问题 H: IP地址和掩码


问题 A: 1的个数

题目描述

输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。

输入

 输入一个整数(int类型)。

输出

这个数转换成2进制后,输出1的个数。

思路:题目说的委婉,其实就是转换为二进制有多少个1

def bcd(x: int):
    res = 0
    while x > 0:
        res, x = res + x % 2, x // 2
    return res


while True:
    try:
        print(bcd(int(input())))
    except:
        break

问题 B: 最小素数对

题目描述

任意一个偶数(大于2)都可以由2个素数组成,组成偶数的2个素数有很多种情况,本题目要求输出组成指定偶数的两个素数差值最小的素数对。

输入

输入一个偶数。

输出

输出两个素数。

思路:根据题目描述,设x, y = n // 2, n // 2,判断x,y是否都是素数,如果不是就x-1,y+1,直到找到为止。

def prime(x: int):
    if x == 2 or x == 3:
        return True
    if x % 6 not in tmp:
        return False
    for i in range(5, x // 2):
        if x % i == 0 or x % (i + 2) == 0:
            return False
    return True


def computed(x: int):
    t = x // 2
    for i in range(0, t - 1):
        if prime(t - i) and prime(t + i):
            return t - i, t + i


tmp = [1, 5]
while True:
    try:
        n = int(input())
        a, b = computed(n)
        print(f"{a}\n{b}")
    except:
        break

问题 C: 今年暑假不AC

题目描述

“今年暑假不AC?”
“是的。”
“那你干什么呢?”
“看世界杯呀,笨蛋!”
“@#$%^&*%...”

确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了。
作为球迷,一定想看尽量多的完整的比赛,当然,作为新时代的好青年,你一定还会看一些其它的节目,比如新--闻--联--播(永远不要忘记关心国--家--大--事)、非常6+7、超级女生,以及王小丫的《开心辞典》等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)

输入

输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。

输出

对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。

思路:贪心问题,每次找满足开播时间限制条件下最早结束的节目,然后更新开播时间限制。

while True:
    try:
        n, tv, sta, cnt = int(input()), [], 0, 0
        if n == 0:
            break
        for _ in range(n):
            tv.append(tuple(map(int, input().split())))
        tv.sort(key=lambda x: x[1])
        for t in tv:
            if t[0] >= sta:
                cnt, sta = cnt + 1, t[1]
        print(cnt)
    except:
        break

问题 D: 隔离14天

题目描述
      为了能够有效切断新冠病毒的传播途径,基于对新冠病毒肺炎的流行病学调查,要求所有与确诊患者有过密切接触者、有疑似症状者、疫情期间去过疫区者或者其他当地卫生部门认为需要隔离者需要居家隔离或者集中隔离14天。其中密切接触者包括与确诊患者乘坐同一交通工具,比如高铁、公交、汽车等并有近距离接触的人。
      如果实施更为严格的防控措施,一辆汽车上有一个确诊患者或者密切接触者,那么该汽车上所有的人都被认为是密切接触者,全部需要自行居家隔离或者集中隔离14天。
      现在假定编号为0的乘客冠状病毒核酸检验呈阳性,请编写一个程序统计需隔离的总人数(包括编号为0的乘客)。

输入

第1行的第1个数字n表示总人数,第2个数字m表示汽车数量;从第2行开始,接下来的m行表示每辆汽车的司乘人员总人数和人员编号(人员编号是一个固定值,可以对应于我们的身份证号码),每一行的第1个数字k表示该汽车的司乘人员总数,接下来的k个数字表示每一个人的编号。

输出

需要被隔离的总人数。
思路:利用python集合内置的函数判断是否存在交集,利用ctl控制隔离人数无增加的时候退出循环。
while True:
    try:
        n, m = map(int, input().split())
        # print(n, m)
        visited, bus, ctl = {'0'}, [], True
        for _ in range(m):
            t = list(input().split())
            t.pop(0)
            t = set(t)
            visited.update(t) if not visited.isdisjoint(t) else bus.append(t)
        while ctl:
            ctl, ll = False, len(bus)
            for i in range(ll - 1, -1, -1):
                if not visited.isdisjoint(bus[i]):
                    ctl, _, _ = True, visited.update(bus[i]), bus.pop(i)
        # print(visited, bus)
        print(len(visited))
    except:
        break

问题 E: 月饼

题目描述

月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼。现给定所有种类月饼的库存量、总售价、以及市场的最大需求量,请你计算可以获得的最大收益是多少。

注意:销售时允许取出一部分库存。样例给出的情形是这样的:假如我们有3种月饼,其库存量分别为18、15、10万吨,总售价分别为75、72、45亿元。如果市场的最大需求量只有20万吨,那么我们最大收益策略应该是卖出全部15万吨第2种月饼、以及5万吨第3种月饼,获得 72 + 45/2 = 94.5(亿元)。

输入

每个输入包含1个测试用例。每个测试用例先给出一个不超过1000的正整数N表示月饼的种类数、以及不超过500(以万吨为单位)的正整数D表示市场最大需求量。随后一行给出N个正实数表示每种月饼的库存量(以万吨为单位);最后一行给出N个正实数表示每种月饼的总售价(以亿元为单位)。数字间以空格分隔。

输出

对每组测试用例,在一行中输出最大收益,以亿元为单位并精确到小数点后2位。(四舍五入)

思路:本质上是部分背包问题,理解题意即可,注意输入为实数。

while True:
    try:
        n, d = map(int, input().split())
        cake, cnt, res = [], 0, 0.0
        for i in input().split():
            cake.append([float(i), 0])
        for i in input().split():
            cake[cnt][1], cnt = float(i), cnt + 1
        cake.sort(reverse=True, key=lambda x: x[1] / x[0])
        cnt = 0
        while d > 0:
            w, v = cake[cnt]
            cnt = cnt + 1
            if d >= w:
                res, d = res + v, d - w
            else:
                res, d = res + d / w * v, 0
        print("%.2f" % res)
    except:
        break

问题 F: 汽车加油问题

题目描述

一辆汽车加满油后可以行驶n千米。旅途中有k个加油站。若要使沿途的加油次数最少,请设计一个有效的算法。

输入

第一行有2个正整数n和k,表示汽车加满油后可行驶nkm,且旅途中有k个加油站。接下来1行中,有k+1个整数,表示第k个加油站与第k-1个加油站之间的距离。第0个加油站表示出发地,汽车已加满油,且在第0个加油站满油不算加油,第k+1个加油站表示目的地。(请处理到文件尾)

输出

最少加油次数。如果无法到达目的地,则输出“No Solution”。

思路:贪心问题,尽可能的走远,实在需要加油的时候才加油。

def greedy(n1: int, a: list):
    s, num = 0, 0
    for i in a:
        if i > n1:
            print("No Solution")
            return
        s += i
        if s > n1:
            s = i
            num += 1
    print(num)
    return


while True:
    n, k = map(int, input().split(' '))
    d = list(map(int, input().split(' ')))
    greedy(n, d)

问题 G: 战场的数目

题目描述

在上题中,假设战场的图形周长为p,一共有多少种可能的战场?
例如,p<8时没有符合要求的战场,p=8时有2种战场:

p=10有9种战场:

 要求输出方案总数模987654321的值。

输入

输入文件最多包含25组测试数据,每个数据仅包含一行,有一个整数p(1<=p<=109),表示战场的图形周长。p=0表示输入结束,你的程序不应当处理这一行。

输出

对于每组数据,输出仅一行,即满足条件的战场总数除以987654321的余数。

思路:待更新。。。

问题 H: IP地址和掩码

题目描述

请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。

所有的IP地址划分为 A,B,C,D,E五类:

A类地址1.0.0.0~126.255.255.255;

B类地址128.0.0.0~191.255.255.255;

C类地址192.0.0.0~223.255.255.255;

D类地址224.0.0.0~239.255.255.255;

E类地址240.0.0.0~255.255.255.255。

私网IP范围是:

10.0.0.0~10.255.255.255

172.16.0.0~172.31.255.255

192.168.0.0~192.168.255.255

子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)

注意二进制下全是1或者全是0均为非法。

IP地址为32位,每8位用.隔开,输入大于32位的IP地址或.与.之间含有数字以外字符的IP地址均为非法IP

注意:

1. 类似于【0.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时可以忽略

2. 私有IP地址和A,B,C,D,E类地址是不冲突的

输入

多行字符串。每行一个IP地址和掩码,用~隔开。

输出

统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。

思路:待更新。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值