本文已参与「新人创作礼」活动,一起开启掘金创作之路。
最近看博文,发现好卷啊,都在刷面试题算法题,说好的摸鱼,原来我才是小丑[dog]
我也刷几题吧,顺便把解题思路记录下来。
解题语言就用C#吧(感觉什么语言都一样,也都差不多,算法核心是解题的思路和技巧)
瓶盖问题
题目:小明买了 n 瓶饮料,三个空瓶可以换一瓶新的饮料,请问小明一共可以喝多少瓶饮料,最后还能剩几个瓶子
分析:
首先最后剩余瓶盖肯定小于 3
假设每次喝完所有饮料,再一次去进行兑换瓶盖
如此循环往复,直到剩余瓶盖 < 3 则停止循环
简单推算一下,假设初始值 10瓶
| 兑换次数 | 喝的瓶数 | 喝完后盖子数 |
|---|---|---|
| 0 | 10 | 10 |
| 1 | 3 | 4 |
| 2 | 1 | 2 |
| 总计兑换2次 | 喝了14瓶 | 剩余2个盖子 |
那这个循环的条件为 cap >= 3,一旦不满足这个条件时,停止循环(即不能兑换)
用do..while表达式再合适不过了
直接上手写了
static void Main(string[] args)
{
Console.Write("请输入小明初始买饮料的瓶数:");
int fir = Convert.ToInt32(Console.ReadLine());//初始瓶数
var tal = fir;//使用新变量保存初始瓶数
int cap = 0;//喝的瓶数
do
{
cap += tal + tal / 3;
tal /= 3;
} while (tal >= 3);
Console.WriteLine("小明买了{0}瓶饮料,一共可以喝{1}瓶,剩余瓶盖{2}个。", fir, cap, tal);
Console.ReadLine();
}
测试
手算了一下,这个结果不对啊,我的写法有问题...
想一下,do中的tal有问题,tal为每次的盖子数,只算了能兑换的瓶盖数,少于3的瓶盖被忽略了
而cap的累加也有问题,第一次可以加上tal,后面只能是喝到tal/3瓶饮料
看来我的第一次尝试完全没有按我分析的方法来,导致写错了
再次尝试,这次需要记录每次剩余的且不够兑换的盖子
static void Main(string[] args)
{
Console.Write("请输入小明初始买饮料的瓶数:");
int fir = Convert.ToInt32(Console.ReadLine());//初始瓶数
var tal = fir;//每次兑换前瓶盖总数
int cap = 0;//剩余不够兑换的空瓶
var sum = 0;//喝的瓶数
//循环体为开始兑换,兑换前,可以喝fir瓶,因此
sum += fir;
do
{
cap = tal % 3;//首先计算每次兑换后手里剩余的瓶盖
sum += tal / 3;//喝的瓶数累加
tal = tal / 3 + cap;//喝完剩余瓶盖总数,供下次兑换
} while (tal >= 3);
Console.WriteLine("小明买了{0}瓶饮料,一共可以喝{1}瓶,剩余瓶盖{2}个。", fir, sum, tal);
Console.ReadLine();
}
看似简单,其实实现起来还是有点小复杂的
可能算法题刷的少吧,挺有意思,分析到实现,过程很重要\
猴子吃桃问题
题目:假设有一堆桃子,猴子每天吃掉总数的一半 + 1个,吃到第 n 天,桃子还剩一个,求桃子总数
同上,先分析一波
这个感觉是反过来的,不知道总数,输入天数,求出总数
完全可以假设啊,比如总共20个桃子,看看能吃几天
| 第?天 | 吃前桃子总数 | 吃桃数量 | 剩余桃子 |
|---|---|---|---|
| 0 | 20 | - | 20 |
| 1 | 20 | 11 | 9 |
| 2 | 9 | 5 | 4 |
| 3 | 4 | 3 | 1 |
注:第0天为初始化数据,未开始吃桃
分析:
每天剩余桃子数有规律,一天是奇数一天是偶数!
吃前桃子数 和 吃完桃子数 奇偶对称(即必一奇一偶)
当剩余桃子为奇数x时,吃前桃子数为 (x+1) * 2
当剩余桃子为偶数x时,吃前桃子数为 x * 2 + 1
规律已找到,直接写代码
public static void Main(string[] args)
{
Console.Write("请输入天数:");
int n = Convert.ToInt32(Console.ReadLine());
int tao = 1;
for (int i = 0; i < n; i++)
{
if (tao % 2 == 0)
{
tao = tao * 2 + 1;
}
else
{
tao = (tao + 1) * 2;
}
}
Console.WriteLine("桃园桃子总数为:{0}",tao);
}
如果没有上面分析,直接贸然写,估计会耽误很长时间吧....
数学基础还是很有必要的,还好我喜欢写之前,先用假数据预测一波,然后再找规律,最后写代码
文末总结
不能眼高手低,看似简单的问题,实际着手写起来可能很棘手,理论分析很重要,但是写出来才显本事
其实很多数学问题,都可以用代码来实现,包括解方程!下次可以搞个鸡兔同笼问题玩玩....