题意:看似给了一个迷宫,每个点能传送到4个地方,问在P时间能否到达终点
分析:其实是一个有向图,可以用邻接矩阵存图,连乘P次看是否能从1到n*m,和floyd的传递背包思想一样
#include <bits/stdc++.h> int tot; struct Mat { int m[30][30]; Mat() { memset (m, 0, sizeof (m)); } void init() { for (int i=1; i<=tot; ++i) { m[i][i] = 1; } } }; Mat operator * (const Mat &a, const Mat &b) { Mat ret; for (int i=1; i<=tot; ++i) { for (int j=1; j<=tot; ++j) { for (int k=1; k<=tot; ++k) { int &r = ret.m[i][j]; r = r | (a.m[i][k] & b.m[k][j]); } } } return ret; } Mat operator ^ (Mat x, int n) { Mat ret; ret.init (); while (n) { if (n & 1) { ret = ret * x; } x = x * x; n >>= 1; } return ret; } int x[4], y[4]; int m, n; int main() { int T; scanf ("%d", &T); while (T--) { scanf ("%d%d\n", &m, &n); tot = m * n; Mat mat; for (int i=1; i<=m; ++i) { for (int j=1; j<=n; ++j) { scanf ("((%d,%d),(%d,%d),(%d,%d),(%d,%d))", &x[0], &y[0], &x[1], &y[1], &x[2], &y[2], &x[3], &y[3]); int pos = (i - 1) * n + j; if (pos == tot) { continue; } for (int i=0; i<4; ++i) { mat.m[pos][(x[i]-1)*n+y[i]] = 1; } getchar (); } } int q; scanf ("%d", &q); while (q--) { int t; scanf ("%d", &t); if (t == 0) { if (tot == 1) { puts ("True"); } else { puts ("False"); } } else { Mat ans = mat ^ t; if (!ans.m[1][tot]) { puts ("False"); } else { int i; for (i=1; i<=tot; ++i) { if (ans.m[1][i]) { break; } } if (i == tot) { puts ("True"); } else { puts ("Maybe"); } } } } puts (""); } return 0; }
时间: 2024-12-28 21:58:59