郑州大学“战疫杯”大学生程序设计在线邀请赛(1)题解(Python版本)

“战疫杯”大学生程序设计在线邀请赛(1)题解

1. 我的账本

简单模拟题:

用一个数组 a ,来统计每个人钱的情况

对于每次买饭的操作,如果1号买饭,1号对应的数也就是a[1] + 5 * 支付钱数即可,而其他的舍友,每次减少支付钱数即可,最后输出没有空行

a = [0] * 7
n = int(input())
for i in range(n):
    x,y = map(int,input().split())
    for j in range(1,7):
        # 如果让舍友买饭,就减下钱数
        if j != x:
            a[j] -= y
    # 买饭的人加上钱数*5
    a[x] += (5*y)
for i in range(1,7):
    if i != 6:
        print(a[i],end=" ")
    else:
        print(a[i],end="")
2. 核酸检测扫码

原本想错了,想成dfs判断连通性的问题,写了几十行代码,发现好多个联通块,输出了十几个点

后来仔细读题,发现直接模拟开搞

思路:读入每行的字符串之后,存入数组

另外开一个vis数组标记每次是否遍历过该点,如果遍历过直接跳过(用于剪枝,可以优化)

另外如果是0开头的直接跳过,还有如果下方和右方点的数量小于8的直接跳过

需要判断的只有1开头的以及没有遍历过的,用64个字符逐个字符对比,如果对比成功,标记这64个点(不重复遍历),并且加入开头点的坐标

最后答案输出前排一下序即可

n,m = map(int,input().split())
g = []
for i in range(n):
    g.append(input())
vis = [[0] * 1010 for _ in range(1010)]
nums = []
s = "1111111110000001101111011011110110111101101111011000000111111111"
for i in range(n):
    for j in range(m):
        if g[i][j] == '0' or vis[i][j] == 1 or i + 8 > n or j + 8 > m:
            continue
        if g[i][j] == '1':
            # 标记是否能够对比成功
            flag = True
            # 逐字符遍历时记录下标
            cnt = 0
            for k in range(i,i+8):
                for l in range(j,j+8):
                    if g[k][l] == s[cnt]:
                        cnt += 1
                    # 逐字符对比失败跳出循环
                    else:
                        flag = False
                        break
            # 对比成功后加入该顶点坐标 并标记该8*8方块上的点
            if flag:
                nums.append([i,j])
                for k in range(i,i+8):
                    for l in range(j,j+8):
                        vis[k][l] = 1
nums.sort(key = lambda x: (x[0],x[1]))
for i in range(len(nums)):
    print(nums[i][0],nums[i][1])

3. 辛苦的楼长

大模拟直接开搞

# 测试组数
t = 3
nums = []
# 映射
dic = {"song" : 0,"jv":1,"liu":2}
# 三个类型的数组
cnt1,cnt2,cnt3 = [],[],[]
dish = [[0] * 3 for _ in range(3)]
for i in range(t):
    n = int(input())
    s = []
    for j in range(n):
        ts = input()
        nums.append(ts)
        s.append(ts)
    morning,moon,night = 0,0,0
    for i in range(len(s)):
        s1,s2,s3,s4,s5 = s[i].split(" ")
        yuan,lou = s1[:-1],s1[-1]
        m = dic[yuan]
        # 通过映射的下标,简化代码
        dish[m][0] += int(s3)
        dish[m][1] += int(s4)
        dish[m][2] += int(s5)
        if m == 0:
            cnt1.append(s[i])
        if m == 1:
            cnt2.append(s[i])
        if m == 2:
            cnt3.append(s[i])
# 关键字排序 注意数组切片的 起始点和终点
cnt1.sort(key = lambda x : (int(x[4]),int(x[6:9])))
cnt2.sort(key = lambda x : (int(x[2]),int(x[4:7])))
cnt3.sort(key = lambda x : (int(x[3]),int(x[5:8])))
# 输出答案
# 先输出每个园区的点餐的宿舍数,早中晚的数量
# 再输出每个园区降序排列后的字符串
print(len(cnt1),dish[0][0],dish[0][1],dish[0][2])
for i in range(len(cnt1)):
    print(cnt1[i])
print(len(cnt2),dish[1][0],dish[1][1],dish[1][2])
for i in range(len(cnt2)):
    print(cnt2[i])
print(len(cnt3),dish[2][0],dish[2][1],dish[2][2])
for i in range(len(cnt3)):
    print(cnt3[i])
4. 等待做核酸

简单模拟,比第三题难度小

没有涉及任何概率论和期望的算法

用一个表简单模拟一下样例

理论到来时间131415161718192021
去的时间151515151515151515
等待时间000123456
期望值0001/302/303/304/305/306/30

所以直接统计转化一下时间为分钟后,累加分子,分子是大于去的时间的累加和

(1 + 2 + … + 14) / 30 ,最后保留两位小数输出

不循环求和也可以通过等差公式来做,O(1)做法

(a1 + an ) * n / 2 ,这样写的转换一下即可

数据范围小无所谓了_

t = input().split("-")
m = input()
nums = []
t1,t2 = t[0],t[1]
m1,m2 = int(t1[:2]) * 60 + int(t1[3:]), int(t2[:2]) * 60 + int(t2[3:])
for i in range(m1,m2+1):
    nums.append(i)
m3 = int(m[:2]) * 60 + int(m[3:])
fz,fm = 0,len(nums)
for i in range(len(nums)):
    if nums[i] > m3:
        fz += (nums[i] - m3)
print("%.2f"%(fz/fm))
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

努力学习前端+Go的小菜鸡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值