题目描述
给一个 n × m n\times m n×m 矩阵迷宫, 第 i i i 行第 j j j 列的值为 c i , j c_{i,j} ci,j , L H LH LH 在迷宫中迷路了,他需要你的帮助。
L H LH LH 当前在 ( 1 , 1 ) (1,1) (1,1) 的位置,出口在 ( n , m ) (n,m) (n,m),这个迷宫有一个计数器,只有当计数器的值模 ( p − 1 ) (p-1) (p−1) 的余数为 0 0 0 时迷宫出口才会开门(出口没有开门意味着即使在 ( n , m ) (n,m) (n,m) 的位置也不能逃出去)。
L H LH LH 每一秒会向迷宫的上下左右四个方向走一步(不可以不走),并且不能走出迷宫的边界,假设 L H LH LH 从 ( i , j ) (i,j) (i,j) 走到了 ( i ′ , j ′ ) (i',j') (i′,j′),然后计数器将会加上 c i ′ , j ′ c_{i',j'} ci′,j′。
特别的,计数器初始是 c 1 , 1 c_{1,1} c1,1。
c i , j = a i , j × p 2 b i , j c_{i,j}=a_{i,j}\times p^{2^{b_{i,j}}} ci,j=ai,j×p2bi,j。
现在 L H LH LH 问你,他最快需要多久才可以走出迷宫。
输入描述
第一行输出三个整数 n , m , p ( 1 ≤ n , m ≤ 10 , 2 ≤ p ≤ 1 0 4 ) n,m,p(1\le n,m\le 10,2\le p\le 10^4) n,m,p(1≤n,m≤10,2≤p≤104)。
接下来输入一个 n n n 行 m m m 列的矩阵 a i , j a_{i,j} ai,j。
接下来输入一个 n n n 行 m m m 列的矩阵 b i , j b_{i,j} bi,j。
0 ≤ a i , b i ≤ 1 0 6 0\le a_i,b_i\le 10^6 0≤ai,bi≤106。
做法
-
注意到要在模 p-1 意义下,因为 a b % p = ( a % p ) b % p a^b\%p=(a\%p)^b\%p ab%p=(a%p)b%p ,所以 c i , j = a i , j % ( p − 1 ) c_{i,j}=a_{i,j}\%(p-1) ci,j=ai,j%(p−1)
-
如此走一遍 bfs 即可
Trick
-
这题如此简单,那么为什么要放到 trick 专栏呢
-
注意下面代码 :
void Show(){while(q.size()){// auto &[x, y, v] = q.front(); q.pop();auto [x, y, v] = q.front(); q.pop();// cout << x << ' ' << y << ' ' << v << ' ' << d[x][y][v] << '\n';for(int i = 0; i < 4; i ++){int a = x + dx[i];int b = y + dy[i];if(a >= 1 && a <= n && b >= 1 && b <= m){int tmpV = (v + A[a][b]) % (p - 1);if(d[a][b][tmpV] == -1){d[a][b][tmpV] = d[x][y][v] + 1;q.push({a, b, tmpV});}}}} }
-
可以看到,这是一个带 pop 的数据结构,这种数据结构进行结构化绑定的时候一定不要加
&
,虽然现在看很 NT,但是写的时候就是容易注意不到,所以放到 trick 专栏里面