解题思路:
注意题目最后的提示,拥有两个瓶子时可以找老板借汽水,然后将三个瓶子换的汽水还给老板
把这个过程简单化,就是可以用两个瓶子作为代价去喝一瓶汽水
好的,那我们就不拿三个瓶子去换了,只要一直去借汽水就可以了(老板表示很凎!)
利用借汽水这个机制,每有两个瓶子就可以喝到一瓶汽水
哪岂不是把输入的数除以2再输出就可以了
确实如此!
参考代码:
#include <stdio.h> int main() { int n; //定义n为现有空瓶子数 while (scanf("%d", &n) != EOF && n) //循环输入n printf("%d\n", n / 2); //输出可以喝到的汽水瓶数 return 0; }
可能有人会觉得,题目里的意思是最后剩两个瓶子时才能用此机制
但我们仔细想想,如果我们有三个瓶子,拿三个瓶子换一瓶汽水,和拿两个瓶子喝一瓶汽水
就结果来看是一样的,都是喝到一瓶汽水并且剩下一个瓶子
所以将输入直接除以二也并不是没有遵循三瓶换一瓶的模式
而且,如果出题人不写借汽水这个机制,反而不能直接用这种方法了(也可以 (n - 1) / 2 直接得到答案)
或许出题人是有意引导做题者去用简单的方法才加了这个条件呢
当然,传统的写法也不难,
瓶子数大于等于3时拿三个瓶子换一瓶汽水,瓶子数等于2时,先借汽水再换汽水,瓶子清零
对于三瓶换一瓶的模式,我这里就模拟一次性换取多瓶,可以减少循环次数
参考代码:
#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; }
0.0分
137 人评分
#include<bits/stdc++.h> using namespace std; int main() { int n , x , y , z, sum = 0 ; int m ; cin >> n; while(n != 0) { x = n / 3; y = n % 3; z = x + y; sum = sum + x; while( z > 2) { x = z / 3; y = z % 3; z = x + y; sum = sum + x; } //cout << z << endl; if(z == 2) sum = sum + 1; cout << sum << endl; cin >> n; sum = 0; } return 0; }
#include <stdio.h> int main(){ int n; scanf("%d",&n); while(n){ printf("%d\n",fun(n)); scanf("%d",&n); } } int fun(int n) { if(n==1) return 0; else if(n==2) return 1; else return n/3+fun(n/3+n%3); }
#include<stdio.h> int main() { int n; //空瓶数 while(scanf("%d",&n)!=EOF&&n) { int temp=0; //换的总数 while(n>=2) { if(n>=3) { int hu=n/3; //换的瓶子 n=n%3; //剩下的空瓶子 temp=temp+hu; n=hu+n; //换与剩下的 } else if(n==2) { temp++; n=0; } } printf("%d\n",temp); } return 0; } 改了一点
#include <stdio.h> int main () { int n, i; while(scanf("%d",&n),n) { i = 0; for(; n>2; ) { n = n-3; n++; i++; } if(n==2) { i++; } printf("%d\n",i); } }
#include<stdio.h> int main() { int n,a; while(scanf("%d",&n)&&n) { a=0; while(n!=1&&n!=2) { a+=n/3; n=n/3+n%3; } if(n==1) printf("%d\n",a); else printf("%d\n",a+1); } return 0; }
第一种方法取巧了,就跟1到100求和一样,应该是循环累加,但你直接输个求和公式了事就没意思了,其实许多题都可以这样人为推算出最终公式,直接输公式,相当于原本交给程序做的你代做了,我之前也弄过,但这就失去练习的意义了
CodeRookie 2022-09-28 15:10:05 |
能从O(n) 的复杂度提高到O(1) 的复杂度可不仅仅是取巧,为了维护练习的意义而去嘲讽算法的意义,实在是本末倒置了,而且能推出最终公式也不是你说的那么简单的事情。人借助程序来完成任务本身就是为了效率,是为了能以少量的劳动完成多量的工作,人为推导公式来提高程序的效率从而达到一劳永逸,才是体现了编程的意义
cdsg 2023-12-22 16:46:33 |
练习的意义就是优化算法,傻瓜式操作不需要练习
C语言程序设计教程(第三版)课后习题10.1 (Java代码)浏览:1436 |
C语言程序设计教程(第三版)课后习题10.4 (C语言代码)浏览:665 |
C语言程序设计教程(第三版)课后习题4.9 (C语言代码)浏览:896 |
计算质因子 (C++代码)浏览:1611 |
淘淘的名单 (C语言代码)浏览:1088 |
WU-蓝桥杯算法提高VIP-交换Easy (C++代码)浏览:1107 |
C语言程序设计教程(第三版)课后习题5.6 (C语言代码)浏览:531 |
1642题解浏览:708 |
A+B for Input-Output Practice (III) (C语言代码)浏览:564 |
有关字符,字符串的输入输出函数说明浏览:477 |