Peter 的烟

目录

一、问题描述

二、用迭代求解

三、用数学方法求解



一、问题描述

题目描述

Peter 有 n 根烟,他每吸完一根烟就把烟蒂保存起来,k(k > 1)个烟蒂可以换一个新的烟,那么 Peter 最终能吸到多少根烟呢?

输入格式

每组测试数据一行包括两个整数 n, k(n > 1,1 < k <= 10^8 )。

输出格式

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

样例输入 1

4 3

样例输出 1

5

样例输入 2

10 3

样例输出 2

14

二、用迭代求解

假设 k = 3,而当前的烟蒂数为 2 时,如果允许借一个烟蒂,Peter 则可以再抽一根烟。但通过题目给出的两组数据,我们可以知道是不允许借烟蒂的。  

#include <stdio.h>

int main()
{
	int n = 0, k = 0;
	scanf("%d%d", &n, &k);
	int counts = n;  // counts 统计 Peter 当前抽了多少根烟
	int cigarette_butts = n;  // cigarette_butts 统计当前烟蒂的个数
	while (cigarette_butts / k)
	{
		counts += cigarette_butts / k;  // 拿当前的烟蒂去换烟
		cigarette_butts = cigarette_butts / k + cigarette_butts % k;
		// 当前烟蒂的个数 = 新换的烟抽完后产生的烟蒂 + 之前没有拿去换烟的烟蒂
	}
	printf("counts = %d\n", counts);
	return 0;
}

三、用数学方法求解

当 Peter 抽完 n 根烟后,产生了 n 个烟蒂,分别用数字 1 ~ n 对每个烟蒂进行编号,然后把这 n 个烟蒂按每组 k - 1 个分为 i 非空组,则有

{1, 2, ..., k-1}, {k, k+1, ..., 2k-2}, ... ...

现在进行这样的操作,先将编号为 k 的烟蒂并入第 1 组,然后将第 1 组的烟蒂拿去换烟,Peter 抽完后再把烟蒂还给第 2 组,依此方式一直操作下去,Peter 可以额外再抽 i - 1 根烟。由于第 i 组非空,即至少有一个烟蒂,所以 i - 1 = ⌊(n - 1) / (k - 1)⌋

那么 Peter 最终抽了 n + ⌊(n - 1) / (k - 1)⌋ 根烟

#include <stdio.h>

int main()
{
	int n = 0, k = 0;
	scanf("%d%d", &n, &k);
	int counts = n + (n - 1) / (k - 1);
	printf("counts = %d\n", counts);
	return 0;
}

如果允许借烟蒂的话,如果 i 个非空组都是每组 k - 1 个烟蒂,则 Peter 可以额外再抽 i 根烟,因为第 i 组可以借一个烟蒂,然后把第 i 组拿去换烟,抽完后再把烟蒂还回去;如果第 i 个组没有 k - 1 个烟蒂,则 Peter 可以额外再抽 i - 1 根烟。

然而无论是哪种情况,Peter 可以额外再抽 ⌊n / (k - 1)⌋ 根烟。那么 Peter 最终就抽了 n + ⌊n / (k - 1)⌋ 根烟。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值