直接暴力模拟啥事没有。
题意
请看原题面:https://loj.ac/p/6619
source: THUPC 2019
思路
维护两个数组,分别是王的直走步数组和士的斜走步数组。
每次走完一步后(以及走第一步前)暴力计算每一个子可以走到哪些位置,然后一切就好办了,就是复杂度有点高,是 $\Theta(n^2m^2Q)$ 的,不过能过。
王
直接遍历王数组,检验是否能走。
士
遍历士数组,检验是否能走。
兵
遍历王数组和士数组。
马
遍历两层,第一步的王数组与第二步的士数组。检验 $\Delta x$ 和 $\Delta y$ 是否皆非 0。如果第一步走王步会到达一个棋子就不枚举第二步。
鸭
与马类似,枚举两层,第一步的王数组和二、三步的士数组。同样检验走第二步之后的 $\Delta x $ 和 $\Delta y$ 是否皆非 0。如果第一步走王步会到达一个棋子就不枚举第二步,如果第二步会到达一个棋子就抛弃这个选择。
象
遍历士数组,如果走一步没有阻挡就检验走两步是否可行。
车
遍历士数组,枚举走了多少步,一直走直到遇到一个棋子,如果遇到对方棋子就停下并认为可以吃到那个子。
细节
这里用 std::unordered_set
来存储可走的地方。
这里用 std::array
来存储棋盘,在枚举可达位置的时候使用 std::array::at()
来访问信息,并在外围套上一个 try {} catch(...) {}
,以避免麻烦的边界判断。
这里用正负来区分红、蓝方。
不知道为什么第 8 行和第 9 行的初始状态写反了……调了半个小时……
代码
1 |
|