【洛谷】P1150 Peter的烟(配数学证明)

题目地址:

https://www.luogu.com.cn/problem/P1150

题目描述:
Peter有 n n n根烟,他每吸完一根烟就把烟蒂保存起来, k k k k > 1 k>1 k>1)个烟蒂可以换一个新的烟,那么Peter最终能吸到多少根烟呢?吸烟有害健康。

输入格式:
每组测试数据一行包括两个整数 n , k n, k n,k 1 < n , k ≤ 1 0 8 1 < n, k \le 10^8 1<n,k108)。

输出格式:
对于每组测试数据,输出一行包括一个整数表示最终烟的根数。

数据范围:
对于 100 % 100\% 100%的数据, 1 < n , k ≤ 1 0 8 1<n, k \le 10^8 1<n,k108

法1:模拟。代码如下:

#include <iostream>
using namespace std;

int main() {
    int n, k;
    cin >> n >> k;

    int count = 0;  // 统计总共的抽烟数
    int end = 0;  // 统计当前的烟蒂数
    do {
        count += n;  // 先抽n根烟
        end += n;  // 新增n根烟蒂
        n = end / k;  // 换烟
        end %= k;  // 计算还剩下的烟蒂数
    } while (n > 0);  // 只要还有烟抽,就继续循环

    cout << count << endl;

    return 0;
}

空间复杂度 O ( 1 ) O(1) O(1),时间复杂度为 O ( log ⁡ k n ) O(\log_kn) O(logkn),也就是 O ( log ⁡ n ) O(\log n) O(logn)

法2:数论。证明在后面。代码如下:

#include <iostream>
using namespace std;

int main() {
    int n, k;
    cin >> n >> k;
    cout << n + (n - 1) / (k - 1) << endl;

    return 0;
}

时空复杂度都为 O ( 1 ) O(1) O(1)

具体证明如下:
假设最后Peter总共抽了 x x x根烟,则其中 ( x − n ) (x - n) (xn)根烟是用烟蒂换来的,所以从头到尾,Peter抽烟产生出来的烟蒂总数至少为 ( x − n ) k (x-n)k (xn)k,之所以是至少,是因为最后有可能剩下来一些烟蒂不够再换烟。其次,因为Peter总共抽了 x x x根烟,所以一共产生出 x x x个烟蒂,但最后抽的那根烟的烟蒂,是没有办法换成烟的,否则如果它换成了烟,就跟”最后抽的“的定义矛盾(当然如果允许借烟蒂,那么最后的烟蒂可以作归还用途,不在讨论范围之列)。(严格来说,还要证明“最后的烟蒂”的存在性。这一点在 k > 1 k>1 k>1时是容易证明的,因为每轮换烟下来,烟蒂的数目严格减少,所以总会到某个时刻,某个烟蒂成为最后的烟蒂)。所以得出这样的不等式: ( x − n ) k ≤ x − 1 (x-n)k\le x-1 (xn)kx1于是得到 x ≤ n + n − 1 k − 1 x\le n+\frac{n-1}{k-1} xn+k1n1下面证明, x x x可以取到 n + ⌊ n − 1 k − 1 ⌋ n+\lfloor\frac{n-1}{k-1}\rfloor n+k1n1
首先,先抽完 n n n根烟,产生了 n n n个烟蒂,然后按照每组 k − 1 k-1 k1个烟蒂分成 i i i个非空组,按数字对烟蒂编号,并设最后一组为 S i S_i Si { 1 , 2 , . . . , k − 1 } , { k , k + 1 , . . . , 2 k − 2 } , . . . , S i \{1,2,...,k-1\},\{k,k+1,...,2k-2\},...,S_i {1,2,...,k1},{k,k+1,...,2k2},...,Si现在进行这样的操作,将烟蒂 k k k并入第一组,换成一根烟后抽掉,再把烟蒂还回第二组,如此这般一直操作下去,可以额外抽 i − 1 i-1 i1根烟。由于 S i S_i Si非空,所以 i − 1 = ⌊ n − 1 k − 1 ⌋ i-1=\lfloor\frac{n-1}{k-1}\rfloor i1=k1n1,由 x x x的定义得到: x ≥ n + ⌊ n − 1 k − 1 ⌋ x\ge n + \lfloor\frac{n-1}{k-1}\rfloor xn+k1n1综上所述, x = n + ⌊ n − 1 k − 1 ⌋ x= n + \lfloor\frac{n-1}{k-1}\rfloor x=n+k1n1

由上面的证明容易知道,如果允许“借尸还魂”,也就是向别人借烟蒂换烟,然后再还回去,则 x = n + ⌊ n k − 1 ⌋ x= n + \lfloor\frac{n}{k-1}\rfloor x=n+k1n

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值