几个算法
1.判断一个点是否在凸边形内部
在游戏开发中,我遇到过这个问题,主要是用来判断玩家鼠标所在点是否在指定的梯形范围内,来响应相关的MOUSEEVENT。
一开始的想法十分简单,用初中的数学即可解决。
思路如下:判断一个点是否在一个边哪一侧,可以转化为判断(0,0)点在一条边的哪一侧。求出N条边的直线方程,然后用N个不等式做&&判定即可。
后来看了《编程之美》ch4.4,发现书中的一个解法更为精妙些。
可以发现,沿着凸边形的各个顶点逆时针走一圈,会发现其内部的点永远都在我们的左手边。
B和C是顶点,A是内部点,则BA必然在BC的左边。
可以根据BA和BC的角度来判断BA是否在BC的左边。若角度<180度,则BA在BC左边;=180度,A在BC的延长线上;>180度BA在BC右边。COS(角度)=(BA 点乘 BC)/ |BA||BC| 即只需判断BA与BC的点乘是否>0即可。
2.判定最大公约数
最简洁的算法:
gcd(a,b) { return !b ? a : gcd(b,a%b); }
时间复杂度:O(lg(b))
3.趣题
A和B分财产,财产一共为99枚铁币和1枚金币,A和B协商轮流拿,每次一个人最多只能拿5个,最少得拿1个,但金币只能放在最后一个拿。A先拿,A第一次应该拿多少铁币,才能确保A最后拿到金币?
思考
其实A有个必胜策略,就是A能控制每一回合至少有多少钱币被拿走,A可以保证不论在B拿多少的情况下每回合两人只拿走6枚钱币。所以,A先拿的话有A –BA-BA-BA-…BA 只要经历100/6 = 16次的回合,A必然会拿到金币。则第一次A应该拿走100%16 = 4枚铁币。
博客地址转移至:http://wuzhiwei.net
浙公网安备 33010602011771号