试题B:小球反弹(第十五届蓝桥杯省赛B组c/c++组)
试题B:小球反弹
我在刷博客的时候看见有人分享了蓝桥杯的题目,我想起了我之前大学打蓝桥杯刷题的时光,还是很怀念当时打比赛的氛围,关于这个小球反弹的题目,我感觉很有意思,我一开始也是走了好多弯路,然后去上了一个厕所,突然茅塞顿开,想到了一个很简单的方法,也看了一圈大家对这道题的结局方法,基本上以遍历枚举出结果为主,和我的思路不太一样,所有想分享给大家看一下我的想法,大家可以先看一下题目呢
错误尝试
我刚看到这个题目的时候,我最先想到的方法是通过定义y=kx+b
的方式来模拟小球反弹的运动曲线,然后通过这个曲线方程来看他到底是碰到了长方形的长还是长方形的宽,因为通过一元一次方程来模拟运动函数,基本上来说k的就两个值在变要么k=17/15
要么k=-17/15
,需要改变的只有b,每一次反弹k就是上一次的k的负数,而b=y-kx,所有只需要,每一次反弹就改变一次k和b就可以得到新的y=kx+b,但这样需要每一次都判断长方形的边,因为你要判断小球反弹的是长方形的长还是宽,这样判断就太复杂了,所有我后面放弃了这个方法
茅塞顿开后的想法
我在想这个小球反弹的时候,突然想到,每一次反弹看似还在一个长方形内,实际上,不就是对原来的长方形对折一下,形成了两个长方形吗?
如果这样想法,实际上小球的运动规矩,就是一直沿着一个方向一直一直往前走,而这个长方形就一直在复制,如果先碰到的是宽,就往右边翻转一个,如果是先碰到长,就往下复制一个长方形
那么依据这个想法就相当于我只需要计算小球从左上方一直往下走,随着长方形的翻转,一直走到了翻转复制后的大长方形的右下角,这个路程就是小球回到原点的路程,这个问题就变成了,我们需要对这个长方形向左负责多少个,向下复制多少,才能让小球刚好到底右下角,那我们假设长方形向左边复制了CopyX
个,向下复制了CopyY
个,而又因为小球往x方向运动和往y方向运动的比例是15/17,相当于我们最终得到的这个大的长方形的长宽比肯定也是要是15/17,所以得到方程
然后通过移动
然后我们知道翻转的次数肯定是一个正整数,相当于我们就是只需要对右边的分数,进行通分得到它的最小分数形式就可以,那么就是我们,如果考场上没有计算器,需要通过代码来弄,就只需写一个求解最小公因数的函数,就可以快速的化简这个分数,最终得到的结果是
那么我们就得到CopyX=1059
,CopyY=1768
,后面就用勾股定理来计算小球的运动规矩最终得到的值是dic =550162599.8851975
遗漏点
对于上面的结果大家是不是很奇怪,好像不是正确答案呀,是不是我们遗漏了什么呢,实际上遗漏的东西,就是我们最终求解的是小球从左上角到右下角的路程,而题目要求是求小球回到原点的路程,那么如果要回到原点实际上是我们刚刚求的结果X2,就可以了,相当于小球进行原路返回,我举例一个简单的例子
因此我们最终的答案是距离=1100325199.77(四舍五入)