【喝汽水游戏,一元一瓶汽水,2个空瓶子换一瓶汽水,给你一些钱,你能喝几瓶】
给你20元,一元能换一瓶汽水,2个空瓶子能换1瓶汽水,20元你能喝几瓶?【答案39】
我们先来分析问题:
首先,我们先干一票大的:用全身家当20元巨款,换20瓶快乐水
你一口气干掉了20瓶快乐水【此时肚子里装了20瓶快乐水】
你得到了20个宝贵的空瓶子
你喝上头,于是又把它们换成了10瓶快乐水
咕噜咕噜,你把他们又干掉了【肚子里装了30瓶快乐水】
喝完又换了5瓶快乐水
又干掉了【肚子里装了35瓶快乐水】
又跑去换成了2瓶快乐水,但是你发现上次的空瓶子留下了一个【快看它快看它】
咕噜咕噜又干掉了2瓶【喝了37瓶】
加上次的空瓶子,现在你有3个空瓶子
又把其中2个空瓶子换成了1瓶快乐水,发现多出了一个空瓶
又干掉了这瓶【肚子里装了38瓶快乐水】
你发现上次多出的空瓶,加现在的刚好又能喝一瓶
【果断干掉它,喝了39瓶】
【于是你20元喝了39瓶汽水】
最后留下来一个空瓶子
【小声:现实中你甚至可以借老板一个瓶子,换成汽水喝完,还老板空瓶子】
…………………………………………我是快乐的分割线………………………………………………
代码的实现
实现代码的时候,我们要通过分析问题,把一个大的的问题,拆成多个小的问题,一步一步实现这些小的问题
我们先很形象的定义一些量
#include<stdio.h>
int main() {
int money = 0;//钱
scanf("%d", &money);
int sum = 0;//喝进肚子里的汽水量
int q = money;//有多少瓶汽水可以喝
int k = 0;//空瓶子数量
return 0;
}
我们先来一轮
把现在汽水喝进肚子里,剩下的瓶子换成汽水
#include<stdio.h>
int main() {
int money = 0;//钱
scanf("%d", &money);
int sum = 0;//喝进肚子里的汽水量
int q = money;//有多少瓶汽水可以喝
int k = 0;//空瓶子数量
sum += q;//把手上的汽水装到肚子里
k = q;//汽水喝完剩下的空瓶子
q=k/2 ;//把空瓶子换成汽水
return 0;
}
我们需要喝多次,肯定有循环套起来:
#include<stdio.h>
int main() {
int money = 0;//钱
scanf("%d", &money);
int sum = 0;//喝进肚子里的汽水量
int q = money;//有多少瓶汽水可以喝
int k = 0;//空瓶子数量
while (k!=1) {//当手上的空瓶子=1个时,换不了了,条件假
sum += q;//把手上的汽水装到肚子里
k = q;//汽水喝完剩下的空瓶子
q = k / 2;//把空瓶子换成汽水
}
printf("%d", sum);
return 0;
}
但真就这样了吗?走你
显然不对,问题出在了哪里呢?
没错,就是多出来的那个空瓶子!并没有传递给下一次循环
解决:我们可以对每一次循环都判断一下,上一次空瓶子数是多少个,如果是奇数个,说明这次循环必定会继承上一次的一个空瓶子【+1】,否则不继承【+0】
实现:
完整代码
#include<stdio.h>
int main() {
int money = 0;//钱
scanf("%d", &money);
int sum = 0;//喝进肚子里的汽水量
int q = money;//有多少瓶汽水可以喝
int k = 0;//空瓶子数量
while (k != 1) {
sum += q;//把手上的汽水装到肚子里
k = q + k % 2;//汽水喝完剩下的空瓶子【k%2,奇数余1,偶数余0】
q = k / 2;
}
printf("%d", sum);
return 0;
}
或者:
常见的写法
我们还可以先喝,拿到空瓶子
#include<stdio.h>
int main() {
int money = 0;//钱
scanf("%d", &money);
int k=money;//喝了多少瓶
int q = k;//空瓶子数
while (k>1) {//空瓶子大于1
q += k / 2;//第二次喝,20空瓶子换成汽水,20+10=30
k = k/2+k%2;//喝完空瓶子数,20/2=10
}
printf("%d", q);
return 0;
}