当前位置:首页 > 数据结构 > 正文
P7963棋局(NOIP2021)
298+

题目大意:往棋盘下子,棋子可以往四个方向走,只要边类型一样,可以走1步、直走、转弯等,请问每个棋子至多可以走多少中位置?(遇到其他不同色棋子会尝试吃子)

题目背景

在输了一晚上的麻将之后,小 z 和小 c 卸掉了手机上的所有牌类游戏。不过这怎么可能阻挡得了他们上课颓废的决心呢?现在他们的目光盯在了棋类游戏上,但他们两个除了天天下飞行棋以外,几乎所有棋类游戏都只懂个大概规则。

“既然我们都会玩但只能玩一点点,不如我们自己搞个缝合怪出来吧!”

于是,在他们的精心脑洞之下,一个融合了围棋、象棋与军棋的奇妙游戏诞生了……

题目描述

游戏在一张长 $n$ 行宽 $m$ 列的网格形棋盘上进行,棋子落在网格的交叉点上,我们不妨记左上角的交叉点的坐标为 $(1,1)$,右下角的交叉点坐标为 $(n,m)$。

棋子分为黑白两色,对局双方各执一方棋子。

每个棋子除了颜色以外还有等级,不妨设 $\mathit{col}_i$ 为棋子 $i$ 的颜色,$\mathit{lv}_i$ 为棋子 $i$ 的等级。另外,棋盘上的网格线共有 $4$ 种状态,对于第 $i$ 条网格线,设其状态为 $\mathit{opt}_i$。

轮到每方下棋时,他可以选择棋盘上的一个己方棋子沿网格线进行移动到另一个交叉点,称为走子。形式化定义走子的过程如下:选择一个坐标序列 $(x_0,y_0),(x_1,y_1),\ldots,(x_k,y_k)$,其中 $k$ 是任意选定的正整数,$(x_0,y_0)$ 是棋子初始的位置,$(x_k,y_k)$ 是棋子最终走到的位置,需要满足:

– 对于任意 $i=0,1,\ldots,k-1$,坐标 $(x_i,y_i)$ 和 $(x_{i+1},y_{i+1})$ 之间必须有网格线直接相连,也就是说**走子必须沿着网格线走**;
– 对于任意 $i\not=j$,必须有 $(x_i,y_i)\not=(x_j,y_j)$,也就是说走子过程中不能经过重复位置,特别地 $(x_0,y_0)\not=(x_k,y_k)$,也就是说**不能原地不动(或走回原地)**;
– 对于任意 $i=1,\ldots,k-1$,坐标 $(x_i,y_i)$ 上必须没有棋子,也就是说**走子时不能越过已有的棋子**;
– 若 $(x_k,y_k)$ 上没有棋子,称为普通走子,否则称为吃子。在吃子过程中,设正在走的棋子颜色为 $\mathit{col}_1$,等级为 $\mathit{lv}_1$,被吃的棋子颜色为 $\mathit{col}_2$,等级为 $\mathit{lv}_2$,则必须满足 $\mathit{col}_1\not=\mathit{col}_2,\mathit{lv}_1\geq\mathit{lv}_2$,换句话说**只能吃与自己颜色不同,且等级不高于自己等级的棋子**。

需要注意的是,由上述定义可以得出,不允许棋子在吃子后继续向前走。

网格线的状态含义如下所述:

– 如果 $\mathit{opt}_i=0$,代表此路不通,走子时不能经过这条网格线;
– 如果 $\mathit{opt}_i=1$,代表这条网格线是一条“普通道路”,每次走子时棋子最多只能经过 $1$ 条普通道路。
– 如果 $\mathit{opt}_i=2$,代表这条网格线是一条“直行道路”,每次走子时棋子可以经过任意条直行道路,但只能**一直沿横向或一直沿纵向走,不能转弯**。如沿直行道路从 $(1,1)$ 经过 $(1,2)$ 走到 $(1,3)$ 是可以的,但是从 $(1,1)$ 经过 $(1,2)$ 走到 $(2,2)$ 不行。
– 如果 $\mathit{opt}_i=3$,代表这条网格线是一条“互通道路”,每次走子时棋子可以经过任意条互通道路,且中途可任意转弯。

同时规定在一次走子过程中,**棋子经过的网格线的状态必须全部相同**,比如从 $(1,1)$ 经过直行道路走到 $(1,2)$ 再经过互通道路走到 $(1,3)$ 是不允许的。

至于如何判断胜负等其它细节,与本题无关,故略去。

小 z 和小 c 开发出这款棋类游戏后,为了提升水平,想了一个训练的策略:一开始棋盘是空的,然后小 c 会每次往棋盘的某个空交叉点上放一枚棋子,小 z 需要快速计算出:若选择这枚新放上的棋子进行一次走子,棋盘上一共有多少个位置是能被走到的?注意:因为这只是思维训练,他们并不会真的走这枚棋子。

可怜的小 z 发现他的计算力不足以算出这个问题,只好向你求助。

输入输出格式

输入格式

每个测试点由多组数据组成。

第一行:一个正整数 $T$ 表示数据组数。

对于每组数据:

第一行:三个正整数 $n, m, q$,分别表示棋盘的行数、列数和游戏的轮数。

接下来 $n$ 行,每行为一个长 $m – 1$ 的字符串,每个字符为 $\texttt{0}$、$\texttt{1}$、$\texttt{2}$、$\texttt{3}$ 中的一个,第 $i$ 行第 $j$ 个字符表示交叉点 $(i, j)$ 连向交叉点 $(i, j + 1)$ 的网格线状态。

接下来 $n – 1$ 行,每行为一个长 $m$ 的字符串,每个字符为 $\texttt{0}$、$\texttt{1}$、$\texttt{2}$、$\texttt{3}$ 中的一个,第 $i$ 行第 $j$ 个字符表示交叉点 $(i, j)$ 连向交叉点 $(i + 1, j)$ 的网格线状态。

接下来 $q$ 行,每行 $4$ 个非负整数 $col_i , lv_i , x_i , y_i$,表示在第 $i$ 轮有一枚颜色为 $col_i$,等级为 $lv_i$ 的棋子放在了交叉点 $(x_i , y_i)$ 上。其中 $col_i = 0$ 表示黑子,$col_i = 1$ 表示白子。保证之前交叉点 $(x_i , y_i)$ 上没有棋子。

输出格式

对于每组数据输出 $q$ 行,每行一个非负整数,表示第 $i$ 枚棋子放置后能走到的交叉点数量。

输入输出样例

输入样例 #1

1
3 3 5
13
22
23
010
233
0 1 2 3
1 2 2 1
1 3 1 2
0 2 3 2
1 3 2 2

输出样例 #1

4
3
3
3
2

输入样例 #2

2
2 3 4
22
33
123
0 2 1 2
0 1 2 1
1 2 1 3
0 3 2 2
3 2 3
3
1
3
32
32
0 2 1 2
1 2 3 2
0 1 2 2

输出样例 #2

3
4
4
2
5
5
1

输入样例 #3

见附件中的 chess/chess3.in

输出样例 #3

见附件中的 chess/chess3.ans

输入样例 #4

见附件中的 chess/chess4.in

输出样例 #4

见附件中的 chess/chess4.ans

说明

**【样例解释 #1】**

放置棋子 $1$ 后,它能走到的位置为 $(2, 1),(2, 2),(3, 2),(3, 3)$。

放置棋子 $2$ 后,它能走到的位置为 $(2, 2),(2, 3),(3, 1)$。

放置棋子 $3$ 后,它能走到的位置为 $(1, 1),(1, 3),(2, 2)$。

放置棋子 $4$ 后,它能走到的位置为 $(2, 2),(3, 1),(3, 3)$。

放置棋子 $5$ 后,它能走到的位置为 $(2, 3),(3, 2)$。

**【数据范围】**

| 测试点编号 | $n \times m \le$ | $q \le$ | 特殊性质 |
|:-:|:-:|:-:|:-:|
| $1 \sim 2$ | $100$ | $50$ | 无 |
| $3 \sim 6$ | $5000$ | $2000$ | 无 |
| $7 \sim 8$ | $2 \times {10}^5$ | ${10}^5$ | 不存在“直行道路”与“互通道路” |
| $9 \sim 11$ | $2 \times {10}^5$ | ${10}^5$ | 不存在“互通道路” |
| $12 \sim 14$ | $2 \times {10}^5$ | ${10}^5$ | 不存在“直行道路” |
| $15 \sim 16$ | $2 \times {10}^5$ | ${10}^5$ | $\mathit{lv}_i = i$ |
| $17 \sim 18$ | $2 \times {10}^5$ | ${10}^5$ | $\mathit{lv}_i = q – i + 1$ |
| $19 \sim 21$ | $2 \times {10}^5$ | $2000$ | $n, m \le 1000$ |
| $22 \sim 25$ | $2 \times {10}^5$ | ${10}^5$ | 无 |

对于 $100 \%$ 的数据,$1 \le T \le 5$,$2 \le n, m \le {10}^5$,$4 \le n \times m \le 2 \times {10}^5$,$1 \le q \le \min \{ {10}^5, n \times m \}$,$1 \le \mathit{lv}_i \le q$,$1 \le x_i \le n$,$1 \le y_i \le m$,$\mathit{col}_i \in \{ 0, 1 \}$。

注:由于本题输入输出规模较大,建议使用较为快速的输入输出方式。

解题思路

考虑每次下子,暴力走遍所有可能的位置,时间复杂度O(q*m*n),期望得分32。需要注意的是,4个方向上的边类型可能不一样,填充的区域可能有交叉,所以四个方向使用独立时间戳填充,但统计的时候,只统计统一询问下没统计过的。

程序实现

对于m*n不超过20万的数据,我们可以开静态数组,然后通过哈希,将二维的点存储一位数组即可。

当然,也可以使用指针,用一维数组实现二维数组。

P7963棋局(NOIP2021):等您坐沙发呢!

发表评论

您必须 [ 登录 ] 才能发表留言!