对于c语言中“汽水瓶”问题的分析

1

问题:

题目描述

有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?

输入格式

输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=100),表示小张手上的空汽水瓶数。n=0表示输入结束,你的程序不应当处理这一行。

问题分析:

大概明白思路:空瓶子换汽水,3个空瓶子换1瓶汽水,或者存在最后两个空瓶子时,借一瓶,再换一瓶。

设计程序:输入数据:最多十个,且输入为0时不处理;

                   算法计算:1.每次将空瓶子数除以3,即一次喝过的饮料瓶数,m1  2.每次将空瓶子数除以3,并加上剩下的空瓶,即是下一轮的空瓶数k。3.当剩下空瓶数小于3时触发两种情况:(1)为2时,喝过的饮料数加一,退出循环。(2)不足2,退出循环

循环上述步奏

最后循环打印喝过的饮料数。

#include<stdio.h>
#define	N 11 //定义好数组大小 

int main(void)
{	
/*初始化*/int drink_bottles[N]={0};//对于当前喝过的饮料瓶进行初始化为0 
		  int empty_bottles[N];//定义目前的空瓶数量 
		  for(int i=0;i<11;i++)empty_bottles[i]=1; //初始化空瓶数量,目的是为了下文判断为0时自动跳出 
		  int frequency=0;//总共输入了几个数据(加上0) 
		  int empty_bottles_0;//防止下文数据丢失 
	
/*存入*/	for(int i=1;empty_bottles[i-1]!=0;i++)//输入每个数据组的空瓶数量 
		{
			scanf("%d",&empty_bottles[i]);
			frequency++;
		}
	
/*算法计算*/	for(int i=0;i<=frequency;i++)//利用算法对问题进行计算, 
		{
			while(empty_bottles[i]!=0)
			{
				drink_bottles[i]+=(empty_bottles[i]/3);//对空瓶数除以3,即是当前空瓶数所换取的饮料 
				empty_bottles_0=empty_bottles[i]/3+empty_bottles[i]%3;//刚才喝过的饮料数加之前没换的空瓶之和 
				empty_bottles[i]=empty_bottles_0;//赋予原值,上文不用是害怕混淆计算 
				if(empty_bottles[i]==2)//判断空瓶数为2,即触发了借老板瓶子的机会 
				{
					drink_bottles[i]++;
					empty_bottles[i]=0;
				}
				else if(empty_bottles[i]<2)//无法换取新的饮料,直接赋予0,方便跳出 
				{
					empty_bottles[i]=0;
				}
			}

		}	
/*打印*/*	for(int i=1;i<frequency;i++) printf("%d\n",drink_bottles[i]); //循环打印数据组 
	
	return 0;
}

相对比较复杂,但我认为优点在于,极其容易理解、易懂。

经过查阅资料发现了及其便捷的写法,以下是从网上查阅的,通过作者讲述,发现了刚开始拥有的空瓶数除以2,就是能够喝过的饮料总和。这个算法,相对比较难想。在构思时并没有多想,呈现了上文中比较冗杂的作品。

对于该算法,本人的导向(如何想出来的)。我们想想容易知道,有两个空瓶就可以换一瓶出来,这就需要思考问题时有分区域思考,换句话说,是否存在一定的规律可寻。

#include <stdio.h>
   
int main()
{
    int n;                              //定义n为现有空瓶子数
    while (scanf("%d", &n) != EOF && n) //循环输入n
        printf("%d\n", n / 2);          //输出可以喝到的汽水瓶数
    return 0;
}

以下是相对正常的思路,实现了当输入为0时,不再进行处理的方法,(scanf("%d", &n) != EOF && n) ,//对于scanf("%d", &n) != EOF的作用,是持续输入数据,scanf函数当输入成功时值为1,当不成功为0。而EOF的值为-1,因此一直循环。

#include <stdio.h>
   
int main()
{
    int n;                              //定义n为现有空瓶子数
    while (scanf("%d", &n) != EOF && n) //循环输入n
    {
        int ans = 0;                    //定义答案 初始化为0
        while (n >= 2)                  //循环n>=2时可继续换汽水
        {
            if (n >= 3)                 //模式一:n>=3时三个瓶子换一瓶汽水
            {
                int temp = n / 3;       //temp记录当前瓶子可换取的汽水瓶数
                ans += temp;            //答案加上temp
                n = n - temp * 3 + temp;//n减去换汽水消耗的瓶子,再加上新得到的瓶子
            }
            else if (n == 2)            //模式二:两个瓶子可以借汽水再换
            {
                ans++;                  //答案加一
                n = 0;                  //瓶子清零
            }
        }
        printf("%d\n", ans);            //输出答案
    }
    return 0;
}

来自dopcpp.com 作者: CodeRookie     发表时间:2021-01-30 22:35:02

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值