C. 光
60分算法:
暴力模拟。
按照题面中说的做,遇到未经过的点时,$ans++$。
对每一个方格,来自每一个方向的情况,
开一个bool数组判断是否经过过。
当遇到已经经过的,即已经有循环,break退出即可。
考虑如何优化暴力。
设这几种情况分别为1,2,3,4。
首先通过手玩,发现一些性质:
性质1:
当且仅当光线遇到情况2,4,每个方格会被来自相对两个方向的光线经过。
如果不遇到情况2,4,每个方格仅会被一个方向的光线经过。
证明:
设(x,y)为四个格子交界处的格点坐标。
考虑向每个方向移动 对x+y的贡献,
x y均+1或-1,x+y的奇偶性不变。
x y分别+1 -1,x+y的奇偶性不变。
于是全程中x+y的奇偶性不会改变。
所以每个方格周围只有两个格点可能被经过,
也就最多被来自两个相对方向的光线经过。
性质2:
光线在无转向的运动过程中,
x+y不变,或x-y不变。
性质3:
由于障碍只有k个,边界的数量只与n,m线性相关。
障碍物的每个方向至多反弹一次。
光线的总反弹次数与n,m,k线性相关。
根据性质2,我们对每个x+y,x-y都开一个set(或经过排序的vector),
将每个障碍物(包括边界)插入对应的set,可以通过二分查找前驱后继,
在一次转向后可快速找到下次转向的位置。
打一堆恶心的特判处理转向位置,统计答案。
光线的总反弹次数与n,m,k线性相关,所以复杂度是可以接受的。
当与起点方向方向相同时走到起点时,可以跳出循环。
记录是否遇到过情况2,4,
如果存在,将ans/2。
复杂度$O(NlogN)$