ZOJ 3497 Mistwald(矩阵快速幂)

题目:

Mistwald


Time Limit: 2 Seconds     
Memory Limit: 65536 KB



In chapter 4 of the game Trails in the Sky SC, Estelle Bright and her friends are crossing Mistwald to meet their final enemy, Lucciola.

Mistwald is a mysterious place. It consists of M * N scenes, named Scene (1, 1) to Scene (M,
N). Estelle Bright and her friends are initially at Scene (1, 1), the entering scene. They should leave Mistwald from Scene (M,
N), the exiting scene. Note that once they reach the exiting scene, they leave Mistwald and cannot come back. A scene in Mistwald has four exits, north, west, south, and east ones. These exits are controlled by Lucciola. They may not lead to adjacent
scenes. However, an exit can and must lead to one scene in Mistwald.

Estelle Bright and her friends walk very fast. It only takes them 1 second to cross an exit, leaving a scene and entering a new scene. Other time such as staying and resting can be ignored. It is obvious that the quicker they leave Mistwald, the better.

Now you are competing with your roommate for who uses less time to leave Mistwald. Your roommate says that he only uses
P seconds. It is known that he lies from time to time. Thus, you may want to code and find out whether it is a lie.

Input

There are multiple test cases. The first line of input is an integer T ≈ 10 indicating the number of test cases.

Each test case begins with a line of two integers M and N (1 ≤
M, N ≤ 5), separated by a single space, indicating the size of Mistwald. In the next
M lines, the ith line contains N pieces of scene information, separated by spaces, describing Scene (i, 1) to Scene (i,
N). A scene description has the form "((x1,y1),(x2,y2),(x3,y3),(x4,y4))"
(1 ≤ xkM; 1 ≤ yk
N
; 1 ≤ k ≤ 4) indicating the locations of new scenes the four exits lead to. The following line contains an integer
Q (1 ≤ Q ≤ 100). In the next Q lines, each line contains an integer
P (0 ≤ P ≤ 100,000,000), which is the time your roommate tells you.

Test cases are separated by a blank line.

Output

For each P, output one of the following strings in one line: "True" if it cannot be a lie; "Maybe" if it can be a lie; "False" if it must be a lie.

Print a blank line after each case.

Sample Input

2
3 2
((3,1),(3,2),(1,2),(2,1)) ((3,1),(3,1),(3,1),(3,1))
((2,1),(2,1),(2,1),(2,2)) ((3,2),(3,2),(3,2),(3,2))
((3,1),(3,1),(3,1),(3,1)) ((3,2),(3,2),(3,2),(1,1))
3
1
2
10

2 1
((2,1),(2,1),(2,1),(2,1))
((2,1),(2,1),(2,1),(2,1))
2
1
2

Sample Output

Maybe
False
Maybe

True
False

题意:给一个图,问从起点到终点能否在P秒完成。

思路:以邻接矩阵存图,设矩阵为A,那么A^P即为走P秒后的图,如果此时起点和终点连通那么就可以。注意中途走到终点后是不能再走的,必须出去,所以把从终点出发的边都删掉就行了。

代码:

#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include<climits>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;

#define PB push_back
#define MP make_pair

#define REP(i,x,n) for(int i=x;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define FORD(i,h,l) for(int i=(h);i>=(l);--i)
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define OI(X) printf("%d",X);
#define RS(X) scanf("%s", (X))
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
#define Swap(a, b) (a ^= b, b ^= a, a ^= b)
#define Dpoint  strcut node{int x,y}
#define cmpd int cmp(const int &a,const int &b){return a>b;}

 /*#ifdef HOME
    freopen("in.txt","r",stdin);
    #endif*/
const int MOD = 1e9+7;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long LL;
typedef pair<int,int> PII;
//#define HOME

int Scan()
{
	int res = 0, ch, flag = 0;

	if((ch = getchar()) == '-')				//判断正负
		flag = 1;

	else if(ch >= '0' && ch <= '9')			//得到完整的数
		res = ch - '0';
	while((ch = getchar()) >= '0' && ch <= '9' )
		res = res * 10 + ch - '0';

	return flag ? -res : res;
}
/*----------------PLEASE-----DO-----NOT-----HACK-----ME--------------------*/

int sz;
struct Matrix
{
    int m[30][30];
    void init()
    {
        MS0(m);
    }
    void show()
    {
        for(int i=0;i<sz;i++)
            for(int j=0;j<sz;j++)
        {
            printf("%d ",m[i][j]);
            if(j==sz-1)
                printf("\n");
        }
    }
};

Matrix mul(Matrix a,Matrix b)
{
    Matrix c;
    c.init();
    for(int i=0;i<sz;i++)
        for(int j=0;j<sz;j++)
        for(int k=0;k<sz;k++)
        c.m[i][j]=c.m[i][j]|(a.m[i][k]&&b.m[k][j]);
    return c;
}
Matrix mypow(Matrix a,int k)
{
    Matrix ans;
    ans.init();
    for(int i=0;i<sz;i++)
        ans.m[i][i]=1;
    Matrix tmp=a;
    while(k)
    {
         if(k&1)
            ans=mul(ans,tmp);
        tmp=mul(tmp,tmp);
        k>>=1;
    }
    return ans;
}
int main()
{
int T;
RI(T);
while(T--)
{
    int m,n;
    RII(m,n);
    Matrix A;
    A.init();
    for(int i=0;i<m;i++)
        for(int j=0;j<n;j++)
    {
        int t=i*n+j;
        char str[30];
        scanf("%s",str);
        int x1,y1,x2,y2,x3,y3,x4,y4;
        x1=str[2]-'0';
        y1=str[4]-'0';
        x2=str[8]-'0';
        y2=str[10]-'0';
        x3=str[14]-'0';
        y3=str[16]-'0';
        x4=str[20]-'0';
        y4=str[22]-'0';
        A.m[t][(x1-1)*n+y1-1]=1;
        A.m[t][(x2-1)*n+y2-1]=1;
        A.m[t][(x3-1)*n+y3-1]=1;
        A.m[t][(x4-1)*n+y4-1]=1;

    }
    sz=m*n;
    for(int i=0;i<sz;i++)
        A.m[sz-1][i]=0;
   // A.show();
    int Q;
    RI(Q);
    while(Q--)
    {int p;
    RI(p);
        Matrix ans=mypow(A,p);
        //ans.show();
    if(ans.m[0][sz-1]==0)
        printf("False\n");
    else
    {   int ok=1;
        for(int i=0;i<sz-1;i++)
        {
            if(ans.m[0][i])
            {
                ok=0;
                break;
            }
        }
        if(ok)
            printf("True\n");
        else
            printf("Maybe\n");

    }
    }
printf("\n");
}

        return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 17:51:00

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

zoj 3497 Mistwald 矩阵快速幂

Mistwald Time Limit: 2 Seconds      Memory Limit: 65536 KB In chapter 4 of the game Trails in the Sky SC, Estelle Bright and her friends are crossing Mistwald to meet their final enemy, Lucciola. Mistwald is a mysterious place. It consists of M * N s

ZOJ 3497 Mistwald 矩阵

利用可达矩阵的幂来判断是否可达 #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <stack> #include <map> #include <set> #include <climits> #include <iostream> #include <string>

zoj 2853 Evolution 矩阵快速幂

在我的电脑上code::blocks运行过不了,但代码是可以AC的,很是郁闷. 问了大神,知道了函数的参数是放在栈区,结构体太大的话,栈就爆了,如是后来就听从大神的意见用引用改写了. 传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1853 #include <stdio.h> #include <string.h> #include <stdlib.h> int Len_Matrix; in

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循环节一定存在,没有排除可能前面一段不循环,后面一段开始周期性循环的可能性.(是我悟性太差吗,为什么大多数题解都只谈