Part 1.1 语言基础 题解
P1909 [NOIP 2016 普及组] 买铅笔
简化题意:有三种铅笔,第 \(i\) 种铅笔一捆有 \(a_i\) 支铅笔,要花 \(b_i\) 块钱。你不能把一捆铅笔拆开来买,你只能同时买一种铅笔。问如果要买大于等于 \(n\) 支铅笔,最少要花费多少块钱。
提示 1
对于每种铅笔,我们最少要买 $\lceil \dfrac{n}{a_i} \rceil$ 捆才能达成目标。
因此,题目相当于让你求出所有 \(\lceil \dfrac{n}{a_i} \rceil \times b_i\) 的最小值。
提示 2
在 Python 中,向上取整和取最小值这样写:
import math # 先导入 math 库
a = 3.7
b = math.ceil(a) # b 是 a 的向上取整后的值
c = 1
d = 2
e = 3
f = min(c, d) # e 是 c 和 d 的较小值
g = min(c, d, e) # 三个数也是没问题的
代码
# 第一种写法(更泛用)
import math
mn = 20000000000000000000 # 先设一个很大的数
n = int(input())
for i in range(3):
a, b = map(int, input().split())
mn = min(mn, math.ceil(n / a) * b)
print(mn)
-------------------------------------------------------
# 第二种写法
import math
n = int(input())
aa, ab = map(int, input().split())
ba, bb = map(int, input().split())
ca, cb = map(int, input().split())
print(min(math.ceil(n / aa) * ab, math.ceil(n / ba) * bb, math.ceil(n / ca) * cb))
P1014 [NOIP 1999 普及组] Cantor 表
提示 1
由于是按 Z 字形走,我们肯定是从左上往右下,按顺序枚举每条对角线。
那如何枚举对角线?实际上,对于每条对角线,它上面的分数,分子与分母的和都是一样的,所以我们从 \(2\) 开始枚举对角线的和 \(\text{sum}\),每个 \( text{sum}\) 都能代表一条分子加分母等于 \(text{sum}\) 的对角线。
提示 2
我们的目标是按 Z 字顺序遍历这条对角线,如果遍历到了第 $N$ 个分数就输出这个分数。
容易发现,当 \(\text{sum}\) 是奇数的时候,分子是 \(1\) 到 \(\text{sum} - 1\) 的顺序,偶数时是 \(\text{sum} - 1\) 到 \(1\) 的顺序。
我们按照奇偶性分类讨论一下,然后按照顺序枚举分子 \(x\),进而算出分母为 \(\text{sum} - x\)。如何判断这个分数是不是我们遍历到的第 \(N\) 个?这个我们只需要额外记一个计数器 \(\text{cnt}\),然后每遍历一个分数就将 \(\text{cnt}\) 增加 \(1\),如果 \(\text{cnt}\) 等于 \(N\) 就输出当前这个分数就行了。
注意:python 的 for 循环是可以倒着遍历的,使用 for i in range(10, 0, -1) 就可以实现 \(10 \to 1\) 的遍历顺序。
代码
cnt = 0
n = int(input())
for sum in range(2, 10000001):
if sum % 2 == 1:
for x in range(1, sum):
cnt = cnt + 1
if cnt == n:
print(str(x) + '/' + str(sum - x))
exit()
else:
for x in range(sum - 1, 0, -1):
cnt = cnt + 1
if cnt == n:
print(str(x) + '/' + str(sum - x))
exit()

浙公网安备 33010602011771号