活动“兑换”问题

活动“兑换”问题

问题:

        某人买了N瓶饮料,但是商家说只要够M个瓶盖就可兑换一瓶饮料。问:这个人总共喝了多少瓶饮料?(不借也不扔)

---------------------------------------------------------------------------------------------------------
通用代码如下:
----------------------------------------------------------------------------------------------------------
#include <stdio.h>
int convert_sb(int m,int n);
int main()
{
    int m,n,sum;
    scanf("%d%d",&m,&n);
    sum = convert_sb(m,n);
    printf("%d\n",sum);
    return 0;
}
//   定义“兑换”函数
//   m:购买数  n:兑换数   t:总数
int convert_sb(int m,int n)
{
    return m + (m-1)/(n-1);
}
------------------------------------------------------------------------------------------------------------
一般代码如下:
-----------------------------------------------------------------------------------------------------
#include <stdio.h>
int main()
{
	int n,s = 0,i;//    i 为未更换的瓶盖数
	scanf("%d",&n);
	i = n;
	s += n;
	while(i > 3)
	{
		s += i/4;
		i = i/4 + i%4;
	}
	printf("%d\n",s);
	return 0;
}

------------------------------------------------------------------------------------------------------------

        解析:通用代码是将购买瓶子数与兑换数联系起来,但是理解起来比较困难。而一般实用代码是将未更换的瓶盖统计起来,这个理解起来很容易,但是用到了循环,数据比较大时运行起来比较慢,个人不建议使用。

    也许所有人都不认准这个公式,认为是胡乱写的,偶然情况下得到了这个公式。下面我来给大家说说:

----------------------------------------------------------------------------------------------------

        下面我给大家举个例子:
    4个兑换一瓶                     3个兑换一瓶                         5个兑换一瓶

1    1  ----  0                   1    1  ----  0                      1    1  ----  0

2    2  ----  0                   2    2  ----  0                      2    2  ----  0

3    3  ----  0                   3    4  ----  1                      3    3  ----  0

4    5  ----  1                   4    5  ----  1                      4    4  ----  0

5    6  ----  1                   5    7  ----  2                      5    6  ----  1

6    7  ----  1                   6    8  ----  2                      6    7  ----  1

7    9  ----  2                     . . . . . .                        7    8  ----  1

  . . . . . .                       . . . . . .                          . . . . . .

  . . . . . .                                                            . . . . . . 


现在我们来看一下,根据上边所举的例子得出:如果M个瓶盖兑换一瓶饮料的话,则每隔M-1就要多加一瓶,
且M又不能为1,故M-1可以作为分母。现在我们再看看分子。
以上式子可以表示为:(注意:1/2=0  0/2=0  2/2=1)

1 + [0,1]/2 = 1    2 + [0,1]/2 = 2    3 + [2,3]/2 = 4    4 + [2,3]/2 = 5
5 + [4,5]/2 = 7    6 + [4,5]/2 = 8    7 + [6,7]/2 = 10    8 + [6,7]/2 = 11
也就是:
1 + [0,1]/2 = 1    ----  n + [n-1,n]/2 = n + 0
2 + [0,1]/2 = 2   ----  n + [n-2,n-1]/2 = n + 0
3 + [2,3]/2 = 4   ----  n + [n-1,n]/2 = n + 1
4 + [2,3]/2 = 5   ----  n + [n-2,n-1]/2 = n + 1
我们会发现,分子的公共部分是[n-1],也就是说求交集。
          
        最后得到m个瓶盖兑换一瓶:s = n+(n-1)/(m-1)。
---------------------------------------------------------------------------------------------------------
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值