Python技术迷

985大厂被裁员工,年近 30,21年计算机毕业,近期被裁,思来想去真不知道应该何去何从!

刷到这个帖,我第一反应是:这哪是求建议啊,这是被裁之后整个人懵了。

985、计算机、进过大厂、北京户口,手里还有点存款,家里也能托一把,单看条件,真不算差。可问题是,人一到快30,被公司一脚踢出来,才发现自己好像除了上班,啥抓手都没有。

Image

最扎心的是那句“不卷”。这年头不卷不是罪,但在大厂混久了,一旦离开那个牌子,心里确实会空。北京留不留,其实别急着用情绪拍板。先把工作试一圈,把能接的活、能转的方向摸清楚。

有户口、有缓冲期,这已经比很多人强了。别先把自己判出局。现在不是世界不要你,是你刚从大厂那套壳里掉出来,还没缓过神。

算法题:镜面反射

光线从左下角打出去,第一次撞到右边墙的时候高度是 q。题目看着像几何,真按反射角去模拟,代码大概率写着写着就歪了。

我一般不碰这种“镜子反弹”的模拟,尤其是坐标一来一回翻转,很容易在边界上吃亏。这个题真正要看的不是反射过程,而是光线什么时候第一次落到某个角上。

房间边长是 p,光线每次横向走 p,纵向就升 q。 如果把镜子展开,不让光线反射,而是把房间一间一间往右复制,光线就变成了一条直线。

比如:

p = 3, q = 1

横向每走 3,纵向升 1
要落到角上,纵向高度必须刚好是 3 的倍数

也就是要找一个次数 k:

k * q 是 p 的倍数

这个 k 表示光线撞了多少次右墙/左墙。 纵向一共上升了多少个房间高度,记作 m:

m = k * q / p

到了这里就别再画图了,看奇偶。

k 是奇数,说明最后在右墙;k 是偶数,说明最后在左墙。 m 是奇数,说明在上边;m 是偶数,说明在下边。

题目里的接收器是:

0:右下角
1:右上角
2:左上角

第一次落角时,不会落回左下角,所以只剩这三个。

我写代码时一般先把 p 和 q 约掉,不直接算最小公倍数,省得数字绕一圈。

from math import gcd

classSolution:
defmirrorReflection(self, p: int, q: int) -> int:
        g = gcd(p, q)

        room_cnt = p // g      # 横向撞墙次数 k
        height_cnt = q // g    # 纵向跨过的房间数 m

if room_cnt % 2 == 1and height_cnt % 2 == 1:
return1

if room_cnt % 2 == 1and height_cnt % 2 == 0:
return0

return2

这里 room_cnt = p / gcd(p, q),其实就是让 k * q 刚好凑成 p 的倍数时,最小的 k。

拿几个例子压一下:

p = 2, q = 1
g = 1
room_cnt = 2  偶数,最后在左墙
height_cnt = 1 奇数,最后在上边
结果是 2

再看一个:

p = 3, q = 1
g = 1
room_cnt = 3  奇数,最后在右墙
height_cnt = 1 奇数,最后在上边
结果是 1

这个题最容易绕进去的地方,是把“反射”当成主线。其实反射只是题目包装,展开房间之后,就剩一个最小倍数问题。

代码最后只有三种判断。

我更喜欢这种写法,变量名虽然不花哨,但现场排错时一眼能看出来:横向过了几间房,纵向过了几层高。比在那里维护方向、坐标、碰撞次数舒服多了。