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