前言
做了一下大学B组的题,原来的信心瞬间都消失了,感觉自己是个弱鸡。。之前还异想天开拿国奖,现在感觉300元不打水漂就不错了。。。大概还有一个月多,难题也指望不上了,只能保证简单题,争取一下中档题。
言归正传,编程的尽头是数学!数学!
题意
原题可以搜到,不多赘述。分析一下重点:
蜂巢中6个方向定义为:东西南北各偏60度+正东西南北
(d,p,q)定义为:向p方向走q步,再向(d+2)mod 6方向(d顺时针120度方向)走q步
问:任意用(d,p,q)表示的两点最少几步到达
分析
明显是个数论问题,有图形,从图形开始分析,找规律。
建立直角坐标系,类似下面这样
![](https://i-blog.csdnimg.cn/blog_migrate/624fc088201afd4601f7b27bc23556e1.jpeg)
假设六边形每条边长度为2,那我们可以知道所有的坐标。
我们发现,移动的最小单位是分别向不同方向移动一步,所以我们用坐标表示每一个方向的最小单位:
direction=[(-2,0),(-1,根号3),(1,根号3),(2,0),(1,-根号3),(-1,-根号3)]
注意:理解题意,这里的移动指的是移动到蜂巢中心位置。
所以每一个蜂巢内(d,p,q)的点都可以用
x=directon[d][0]*p+direction[(d+2)%6][0]*q
y=direction[d][1]*p+direction[(d+2)%6][1]*q 表示
接下来我们考虑几种可能出现的情况:
b,c在同一行走几步:
一步跨越两个单位坐标,因此走 |x1-x2|//2 步。
b在c的左上走几步:
第一种情况:
b向右下(4方向)走到与c同方向的位置再向右(3方向)平移到c。
走的步数是:
(y2-y1)/根号3 *2+(x2-(x1+(y2-y1)/根号3 )//2)
数学问题,画个图就能出来。
第二种情况:
b向右下移动时移动到了c的左边。
这时我们发现并不是最少步数,因此优化此解:
![](https://i-blog.csdnimg.cn/blog_migrate/3ede1d3ba6dd4db33e5c89b4eb543262.jpeg)
将b向右下移动到c的正上方向,再走折线。(具体看图)
由图形角度60度可知:
走折线的路线为:(y1-y2)/根号3+2*(x2-x1)
代码
![](https://i-blog.csdnimg.cn/blog_migrate/f6960e83c7e5abb63eb201f8d927a940.jpeg)
具体就是枚举不同情况。
结论
图形问题大多需要数学问题解决,我的数学方面还要加强。
枚举的时候要注意所有情况,不要漏掉。