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

python版本答案,也有利用python的特性偷懒的写法,只是供有缘人图一乐。

目录

问题A:十六进制

问题B: 平行四边形

问题C:冰冻三尺

问题D:三家人

问题E:汽水瓶

问题F:数字整除

 问题G: 超大型 LED 显示屏

问题H:聊天止于呵呵


问题A:十六进制

题目描述:

        小米同学最近在学习进制转换。众所周知,在表示十六进制数时,除了0-9这九个阿拉伯数字外,还引入了“A”、“B”、“C”、“D”、“E”和“F”这六个英文字母(不区分大小写)。
现在给你一个十进制正整数,请问在将其转换为十六进制之后,对应的十六进制表示中有多少位是字母?

答案:

        利用divmod函数得到商和余,使用一个列表做16进制的检索表。

hexs = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
n = int(input())
cnt = 0
while n > 0:
    n, index = divmod(n, 16)
    if hexs[index] in ['A', 'B', 'C', 'D', 'E', 'F']:
        cnt += 1
print(cnt)

问题B: 平行四边形

题目描述:

        Kimi想用“*”号构成一个平行四边形并在屏幕上输出。
当输入一个大于等于2的正整数N时,屏幕上将显示一个由N*N个“*”组成的平行四边形。
例如:输入3,输出如下平行四边形。
  ***
 ***
***

答案:

        可以从最低行开始拼接,然后后一个字符串就是前一个拼接字符串前加空格,然后将新得到的字符串加入列表。使用列表的pop函数,达到类似栈弹出的输出效果。

n = int(input())
strings = ['*' * n]
for _ in range(1, n):
    strings.append(' ' + strings[-1])
# print(strings)
while strings:
    print(strings.pop())

问题C:冰冻三尺

题目描述:

        表面意义是冰冻了三尺,并不是一天的寒冷所能达到的效果。比喻一种情况的形成,是经过长时间的积累、酝酿的,积少成多。

冰冻三尺非一日之寒,准确意思是:形成一项事物,是需要长期的积累,不是一天两天可以完成的,任何事的发生都有其潜在的,长期存在的因素,不是突然之间就可以形成的。贬义时,多用来形容矛盾的日积月累之形成;褒义时,则形容成绩取得实属来之不易。

假设极寒之地每天冰冻1尺,请问经过N天后累计冰冻了几尺?

答案:

while True:
    nnnnnnnn = int(input())
    if nnnnnnnn != 0:
        print(nnnnnnnn)
    else:
        break

问题D:三家人

题目描述:

        有三户人家共拥有一作花园,每户人家的太太均需帮忙整理花园。A太太工作了 5天,B太太则工作了 4天,才将花园整理完毕。C 太太因为正身怀六甲无法加入她们的行列,便出了 90 元。请问这笔钱如何分给 A、B二位太太较为恰当?A应得多少元?
90/(5+4)*5=50元?如果这么想你就上当了!正确答案是 60元。如果没想通的话再想想吧。 下面回答一个一般性的问题:假定 A 太太工作了 x 天,B 太太工作了 y 天,C 太太出了 90 元,则 A太太应得多少元?输入保证二位太太均应得到非负整数元钱。

答案:

        小坑点就是其他两个太太也有自己该做的任务,两个太太减去本身的任务以后,才是帮C太太做的。

t = int(input())
while t > 0:
    t -= 1
    x, y, z = map(float, input().split())
    s = (x + y) / 3
    if x <= s:
        a = 0
    elif y <= s:
        a = 1
    else:
        a = (x - s) / s
    print("%.f" % (a * z))

问题E:汽水瓶

题目描述:

        有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?

答案:

while True:
    n = int(input())
    if n == 0:
        break
    queue = [n]
    cnt = 0
    while queue:
        x = queue.pop(0)
        if x > 2:
            a, b = divmod(x, 3)
            cnt += a
            queue.append(a + b)
        elif x == 2:
            cnt += 1
    print(cnt)

问题F:数字整除

题目描述:

        定理:把一个至少两位的正整数的个位数字去掉,再从余下的数中减去个位数的5倍。当且仅当差是17的倍数时,原数也是17的倍数 。

        例如,34是17的倍数,因为3-20=-17是17的倍数;201不是17的倍数,因为20-5=15不是17的倍数。输入一个正整数n,你的任务是判断它是否是17的倍数。

答案:

        这里偷懒用了python对整数存储的特性,这种大数python是可以存下的,真正的算法可以在CSDN搜索“大数运算”。

while True:
    n = int(input())
    if n == 0:
        break
    else:
        print(1) if n % 17 == 0 else print(0)

 问题G: 超大型 LED 显示屏

题目描述:

        你是学生会体育部长,负责组织一年一度的校篮球比赛。马上就要决赛了,你希望吸引更多的 人来看比赛,因此打算更新一下设备,用一个超大的 LED屏幕来显示比分。当然,电也不是 不要钱的,所以你决定先分析一下往年的比赛,估计一下大概要耗多少电。 

 

如上图,每个数字由 7条线段组成,每条亮着的线段每秒钟耗电量为 1个单位。线段不亮的时 候不耗电。为了省电,比分不显示前导 0(不过 0分的时候要显示数字 0)。 
你的 LED显示屏共包含 6个数字,即双方的比分各有 3 位数。 

 答案:

        稍微注意刚开始分数都为0的情况,然后直接模拟

def clock(old_t: str, now_t: str):
    h1, m1, s1 = map(int, old_t.split(':'))
    h2, m2, s2 = map(int, now_t.split(':'))
    return (((h2 * 60) + m2) * 60 + s2) - (((h1 * 60) + m1) * 60 + s1)


def light(num: int):
    if num == 0:
        return cost[num]
    res = 0
    while num > 0:
        res += cost[num % 10]
        num //= 10
    return res


cost = [6, 2, 5, 5, 4, 5, 6, 3, 7, 6]
states = ['START', 'SCORE', 'END']
case = 0
while True:
    try:
        strings = input().split()
        state = strings.pop(0)
        if state == states[0]:
            scores = {'home': 0, 'guest': 0}
            now = strings.pop(0)
            result = 0
        elif state == states[1]:
            old = now
            now = strings.pop(0)
            who = strings.pop(0)
            # print(clock(old, now), scores, result)
            result += clock(old, now) * (light(scores['home']) + light(scores['guest']))
            scores[who] += int(strings.pop(0))
        else:
            old = now
            now = strings.pop(0)
            result += clock(old, now) * (light(scores['home']) + light(scores['guest']))
            # print(clock(old, now), scores, result)
            case += 1
            print(f'Case {case}: {result}')
    except:
        break

问题H:聊天止于呵呵

题目描述:

        现代版)俗话说:流言止于智者,聊天止于呵呵。输入一段聊天记录,你的任务是数一数有 多少段对话“止于呵呵”,即对话的最后一句话包含单词 hehe或者它的变形。 
具体来说,我们首先提取出对话的最后一句话,把所有非字母的字符替换成空格,把所有字符 替换成小写,然后导出一个单词列表(由空格隔开),只要列表中的任何一个单词是 hehe,这 段对话就算作“止于呵呵”。比如,"Hi! Are you OK?" 会变成四个单词:hi, are, you, ok。注 意,单词列表可以是空的(比如,这句话是:"?!?!!") 
        有些人喜欢使用 hehe的变形,这些变形也应被视为“呵呵”。为了简单起见,本题只考虑由 n(n>1)个 he连接而成的单词,比如 hehehe或者 hehehehe。注意,以 hehe为连续子串的其他单 词不应视为“呵呵”,比如 hehee,或者 ehehe。 
每两个不同人之间的所有对话算作“一段对话”。 

 答案:

        题目描述里其实已经给出了算法思路,使用字典(dict)实现一下即可。

def change(string: str):
    new = ''
    string = string.lower()
    for i in range(len(string)):
        if not string[i].isalpha():
            new += ' '
        else:
            new += string[i]
    return new.split()


def check(string: str):
    for index in range(len(string)):
        if not string[index] == char[index % 2]:
            return 0
    return 1


char = ['h', 'e']
peoples = dict()
while True:
    try:
        name, say = input().split(': ')
        names = name.split('->')
        names.sort()
        peoples[''.join(names)] = change(say)
    except:
        break
# print(peoples)
cnt = 0
for words in peoples.values():
    for word in words:
        if word[0] == 'h' and len(word) > 3:
            cnt += check(word)
print("%.f" % (cnt * 100 / len(peoples)) + '%')
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您讲解一下 HNUCM 最小生成树(Prim)的算法过程。 首先,Prim 算法是一种贪心算法,用于求解带权无向连通图的最小生成树。下面是具体的算法过程: 1. 选取任意一个顶点作为起点,将其加入到生成树中。 2. 找到与已经加入到生成树中的顶点相邻的所有顶点,并计算它们与生成树的距离。 3. 从这些顶点中选取距离最小的顶点,将其加入到生成树中。 4. 重复步骤2和3,直到生成树中包含了所有的顶点。 在具体实现时,可以使用一个数组来记录每个顶点是否已经加入到生成树中,以及另一个数组来记录每个顶点与生成树的距离。每次选择距离最小的顶点时,可以使用一个最小堆来优化。 至于 HNUCM 最小生成树 Prim 算法的具体实现,可以参考以下代码: ```python import heapq def prim(graph): n = len(graph) visited = [False] * n distance = [float('inf')] * n distance[0] = 0 heap = [(0, 0)] result = 0 while heap: (d, u) = heapq.heappop(heap) if visited[u]: continue visited[u] = True result += d for v, weight in graph[u]: if not visited[v] and weight < distance[v]: distance[v] = weight heapq.heappush(heap, (weight, v)) return result ``` 这段代码实现了 HNUCM 最小生成树 Prim 算法的过程,其中 graph 是一个邻接表表示的带权无向连通图,每个元素是一个二元组 (v, w),表示从节点 u 到节点 v 有一条边权为 w 的边。算法的返回值是最小生成树的总权值。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值