Loading

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()
posted @ 2026-03-22 21:38  DE_aemmprty  阅读(5)  评论(0)    收藏  举报