思路:
第一个子任务里,车和卒是同一行的,显然车只要直接把卒吃掉即可。
根据算法一的思路,如果卒和车在同一行或者同一列,我们直接输出 1。好了下面我们讨论 x1≠x2, y1≠y2 的情况。
诶,我们接着来看第四个子任务!为什么直接跳到了第四个呢,因为我们需要想想一般情况下这个题的答案到底是多少。想要分类讨论,就要先想想答案最大是多少。而在第四个子任务里,卒和车都在棋盘靠中心的位置,所以我们至少可以不用考虑棋盘边界对答案的影响。
卒和车都是左右对称的,所以我们不妨设 y1<y2,即车在卒右边。如果 y1>y2,我们可以做一个水平的镜像对称。虽然不一定会体现在代码里,但至少思考的时候我们不用考虑车在卒左边的情况了。
现在我们随手画一个车在卒右边的情况:
诶,然后我们来试试怎么把卒吃掉。我们先跑到卒的下面一行,这样卒就不敢往下走了,只能左右乱窜。然后我们就像样例一的第二组数据一样做:在卒的下面一行撒一行毒雾出来,卒仍然只能左右乱窜;现在我们跑到卒所在的那一行,卒仍然只能左右乱窜;接下来我们就把它吃掉。这样我们就得到了一个四步将卒吃掉的策略。
那么,只要不在同一行同一列,就肯定是 4 了吗?如果卒和车离得很远的话,确实没有任何办法再优化 —— 首先如果卒既可以横向走,也可以向下走,那么卒肯定没办法在一步内被你吃掉,所以在吃掉卒之前,我们要么用毒封住卒的左右两侧,要么用毒封住下面。但封住左右两侧是需要走很多步的。因为如果你先封左边,卒可以往反方向走,导致你只能努力把它卡在某两列或者某三列,然后它就可以在里面继续乱走。经过一番尝试你会发现先封左侧或者先封右侧都是不可能比 4 步更优的。如果要封下面,那么晚封不如早封,所以就变成上图的那个策略了。
所以就是要考虑卒和车靠得很近的情况。可以发现,只要初始的时候不在卒所在的下一行,好像都没什么意义,还是得走到那行放毒。。如果在卒所在的下一行,那么上图的策略就可以省掉第一步了,于是 3 步就可以吃掉卒。(当然你看样例也会发现有这个情况)
特判掉这个情况,就可以过第四个子任务了。
通过上述思路理清楚答案不超过 4,或者通过看样例之类的其他方式攒足了对“答案很小”的信心之后,你就可以使用暴力美学解决本题了。我认为也是比赛时最经济的一种做法。
因为答案不超过 4,所以卒之多只会走 3 步,而车走到离卒太远的地方也毫无意义。
所以我们就可以在卒的初始位置附近,向各个方向延申常数格(仔细想想会发现常数取 4 就足够了,不够自信也可以取一点,再逐步减小看看是否影响答案),然后只在这个小范围内进行搜索。如果车初始时不在这个范围内,不妨把车直接挪到离车最近的格点。
好的,迭代加深!博弈搜索!游戏规则也不是很复杂,按照题面把代码写出来就好了!赛场上大部分 AC 的选手正是用