矩阵快速幂 ZOJ 3497 Mistwald

题目传送门

题意:看似给了一个迷宫,每个点能传送到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

矩阵快速幂 ZOJ 3497 Mistwald的相关文章

zoj 2974 Just Pour the Water矩阵快速幂

Just Pour the Water Time Limit: 2 Seconds      Memory Limit: 65536 KB Shirly is a very clever girl. Now she has two containers (A and B), each with some water. Every minute, she pours half of the water in A into B, and simultaneous pours half of the

zoj 2853 Evolution(矩阵快速幂)

Evolution is a long, long process with extreme complexity and involves many species. Dr. C. P. Lottery is currently investigating a simplified model of evolution: consider that we haveN (2 <= N <= 200) species in the whole process of evolution, inde

ZOJ 3690 &amp; HDU 3658 (矩阵快速幂+公式递推)

ZOJ 3690 题意: 有n个人和m个数和一个k,现在每个人可以选择一个数,如果相邻的两个人选择相同的数,那么这个数要大于k 求选择方案数. 思路: 打表推了很久的公式都没推出来什么可行解,好不容易有了想法结果WA到天荒地老也无法AC.. 于是学习了下正规的做法,恍然大悟. 这道题应该用递推 + 矩阵快速幂. 我们设F(n) = 有n个人,第n个人选择的数大于k的方案数: G(n) = 有n个人,第n个人选择的数小于等于k的方案数: 那么递推关系式即是: F(1)=m?k,G(1)=k F(n

ZOJ 2794 Just Pour the Water 【矩阵快速幂】

给你n个杯子,每次有特定的到水规则,倒m次请问最后每个被子里还有多少水 我们很容易发现每次变化的规则相同,那么可以set 一个矩阵存放 然后多次倒水就相当于矩阵相乘,在m 范围达到(1<= M <= 1,000,000,000) 的情况下使用矩阵快速幂再好不过 这到题目注意的一点是,得使用Double 变量,如果使用FLoat会导致Wrong Answer Source Code: //#pragma comment(linker, "/STACK:16777216") /

zoj 3538 Arrange the Schedule(矩阵快速幂)

Arrange the Schedule Time Limit: 1 Second      Memory Limit: 65536 KB In Summer 2011, the ZJU-ICPC Team has a n-days training schedule. ZJU-ICPC Team has been divided into 4 Group: Akiba, BiliBili, CIA, Double(Group A, B, C, D). There is a group in c

【ZOJ 2974】Just Pour the Water(矩阵快速幂)

传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2974 题意 给出n个杯子与初始水量同时进行操作 将其中的水同时平均分入所指定的杯子 进行x次后 输出杯子剩余水量 刚拿到这个题,第一反应是递推找规律,但是因为每个杯子的初始水量是未知的,所以能找的只是每个杯子水量与其余杯子水量的关系. 但是看到了操作次数巨大,而且最多只有20个杯子,感觉可以用快速幂去做. 我们假设矩阵a[i][j]代表第i个杯子的水有a[i][j

ZOJ 2105 Number Sequence(矩阵快速幂)

题意: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7. 给定A,B,求f(n). 法一: 网上较多的题解都提到了寻找1 1循环节的方法,的确非常巧妙,每位0~6,共7种可能,相邻两位共49种可能,因此循环周期至多为49,一旦出现相同数对,那么其后必相同.但是,该方法只是简单提及了49,却并没有证明1 1循环节一定存在,没有排除可能前面一段不循环,后面一段开始周期性循环的可能性.(是我悟性太差吗,为什么大多数题解都只谈

ZOJ 3256 Tour in the Castle 矩阵快速幂加速

题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3256 题意:给一个n*m的棋盘,求从左上到左下的经过所有格子的方案数 在左边加一列问题就变成了求回路 由于m很大,所以我们需要按列dp 构造出矩阵后,用矩阵快速幂加速 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include&l

递推关系转矩阵快速幂

一些递推关系如f(n) = af(n-1)+bf(n-2)+...+tf(n-k)等,在n很大的时候,O(n)的算法都不能满足要求的时候,往往可以化为矩阵快速幂来做,复杂度可以降为O(logn),大大减少了运行时间. 如何将一个递推关系式化为矩阵呢? 比如这样一个递推关系: f(n) = 2*f(n-1)+4*f(n-2) 先列出几个等式: f(n) = 2*f(n-1)+4*f(n-2) f(n-1) = 2*f(n-2)+4*f(n-3) 然后就有: 就可以将左边矩阵做n-2次幂,再乘初值,