【竞赛经历】CSDN第39期竞赛题解

1 前言

  第一次心血来潮参加CSDN的竞赛,看了一下往期的比赛,感觉不是很难,加上又可以用python解题,所以果断报了个名,没想到运气不错,近了前十,这里将根据我的答题报告来做个小结。

【竞赛经历】CSDN第39期竞赛题解_第1张图片

2 题解

2.1 第一题:圆小艺

  最近小艺酱渐渐变成了一个圆滑的形状-球!! 小艺酱开始变得喜欢上球! 小艺酱得到n个同心圆。 小艺酱对着n个同心圆进行染色。 相邻的圆范围内不能有相同的颜色。相隔一层的圆颜色相同。 小艺酱想知道两种颜色中最外层圆的那种颜色总共染了多少?

  这道题不是很难,相当于算圆环的面积,不过圆环是间隔的。这里需要注意的是,染色是从外面先开始

import math
n = int(input())
r = [int(i) for i in input().split()] #这种输入方式挺高效的
r.sort(reverse=True) #记得排序
sum1 = 0.
for i in range(n):
sum1 += math.pi * r[i]**2 * (-1)**i
print(format(sum1, ".3f")) #输出精度把握不住的时候,可以多试试几种方案
#print(round(sum1, 3))

2.2 第二题:近视的小张

  小张和他的 M 个朋友来到了一个十分神奇的地方,在这里有 N 个 柱子, 对于每个 1 <= i <= N, 第 i 个柱子都有两个属性 : H[i], P[i]。
  H[i] 表示柱子 i 的高度, 而 P[i] 则表示柱子 i 当前所处的位置,题目保证同一个位置不会有多个柱子。
  在一个柱子 i 在另一个不比他低的柱子 j 的后面时 (P[i] > P[j] && H[i] <= H[j]), 这个柱子会被遮挡住, 也就不再能被清晰的看到。
  小张和他的朋友们在位置 0 休息时, 发现似乎朋友们能清晰看到的柱子数量并不相同,在他反复思考后, 他认为这可能是近视度数导致的,于是他询问了每一个朋友的近视度数 A[i]。
  为了方便计算, 我们认为对于朋友 j 来说,对每一个柱子 i, 如果有 P[i] > A[j], 那么第 i 个柱子无法被清晰看见。
  请你计算出每个小张的朋友能清晰看到的最远一个柱子的位置, 如果那个朋友一个柱子都没有清晰看到, 请输出 -1。

  这道题可能初看有点绕,我当时是最后做的,有一个样例没通过,而且有一个代码我本地运行没有任何问题,在网站上就是报错,也没明白错在哪。这里的A[i]应该理解为“目力”,越大看得越远,近视度数会产生误解。
  由于这道题数据量不大,完全可以遍历每一位好朋友,针对每位朋友再按照位置顺序遍历每根柱子,这样来判断柱子是否可见。
  当然,鉴于python优秀的迭代器功能和简洁的代码,也可以先排序,然后搞一个函数,得到目力范围内最高前最靠前的柱子,然后输出这个柱子的高度
  以下是两种实现方式的python代码


M,N = [int(i) for i in input().split()]
H = [int(i) for i in input().split()]
P = [int(i) for i in input().split()]
A = [int(i) for i in input().split()]

# 测试用
# import random
# M = 1000
# N = 900
# H = [random.randrange(1000) for _ in range(N)]
# P = [random.randrange(1000) for _ in range(N)]
# A = [random.randrange(1000) for _ in range(M)]

result1 = []
result2 = []

# 先排序,按照位置排序,同时高度也要同步排序
P,H = [list(x) for x in zip(*sorted(zip(P,H)))]

T = [-1]*M
for i in range(M):
    for j in range(len(P)):
        if(A[i] >= P[j]):
            if( j==0 or H[j] > max( H[:j] )): #这一行代码当时反复报错,但本地运行没有问题,不知道为啥
                T[i] = P[j]
            
for i in T:
    # print(i)
    result1.append(i)

# 另一种做法:
P,H = [list(x) for x in zip(*sorted(zip(P,H)))] 
argmax = lambda ls:ls.index(max(ls)) if ls else -1
# 得到一个列表当中最大且最靠前的数值对应的下标

for a in A:
    P1 = list(filter(lambda x:x<= a,P)) #找到目之所及的柱子
    idx = argmax(H[:len(P1)])
    result2.append(P[idx] if idx != -1 else -1)
    print(P[idx] if idx != -1 else -1)

2.3 第三题:小股炒股

已知n天后的股票行情,现在已有的本金是m, 规定只能入手一次股票和抛售一次股票。 最大收益(含本金)是?

  这道题给出的是往后n天的股票行情,然后只允许买卖一次,也就是说要在这些天当中挑两天差值最大的。同时还要注意,如果本金大于股票价格,可能一天可以买多支股票(同一天买就算一次)。

  看代码:

n,m = [int(i) for i in input().split()]
p = [int(i) for i in input().split()]
max1 = 0
for i in range(n):
if(p[i]<=m):
t = int(m / p[i])
maxp = max(p[i:])
max1 = max(max1,t*(maxp - p[i]))
print(max1+m) #记得加上本金

2.4 第四题:买铅笔

  P老师需要去商店买n支铅笔作为小朋友们参加编程比赛的礼物。她发现商店一共有 3 种包装的铅笔,不同包装内的铅笔数量有可能不同,价格也有可能不同。为了公平起 见,P老师决定只买同一种包装的铅笔。 商店不允许将铅笔的包装拆开,因此P老师可能需要购买超过 n 支铅笔才够给小朋友们发礼物。 现在P老师想知道,在商店每种包装的数量都足够的情况下,要买够至少 n 支铅笔最少需要花费多少钱。

  注意,这里是只挑一种铅笔买,满足数量的前提价格最低即可。最简单的做法就是把每一种铅笔都算出来(因为总共只有3种铅笔),然后求价格的最小值即可。不过这里要注意算数量时要想上取整,用的是math库中的ceil函数。
  直接看代码:

n = int(input())
p1 = [int(i) for i in input().split()]
p2 = [int(i) for i in input().split()]
p3 = [int(i) for i in input().split()]
import math
t1 = math.ceil(n/p1[0])
t2 = math.ceil(n/p2[0])
t3 = math.ceil(n/p3[0])
print(min(t1*p1[1], t2*p2[1], t3*p3[1]))

3 比赛注意事项

  由于是第一次参赛,确实很多规则不太清楚,这里简单总结一下。

  • 如果使用python,只能使用内置函数和内置库,不能使用如numpy这样高级的第三方包
  • 过程当中鼠标焦点不能离开题目页面,也就是不能进行本地调试,感觉不太好,但也更加公平。
  • 要善用自测功能,查看输出的结果,也算是一种调试方案了吧。
  • 此外,就是提交测试按钮点击之间有时间间隔,要注意合理安排时间(如果想抢时间的话)

你可能感兴趣的:(学习笔记,学习,python,csdn竞赛,题解)