原文链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3497
给出n*m个点,然后每个点会往其他的点移动,然后给定移动的方向点。求判断,在规定步数下,一定能到达终点输出true,不一定就maybe,否则就False。
把n*m个点离散化,然后给定的点到点就相当于在一个(n*m)*(n*m)的图中建立连接,然后对这个矩阵快速幂就是答案。需要注意的是,到达最后一个点的时候就不动了,所以最后一个点是不操作的。
#include<bits/stdc++.h>
using namespace std;
typedef vector<int> vec;
typedef vector<vec> mat;
int t,n,m,q;
#define mod 100007;
mat mul(mat a,mat b)//矩阵相乘
{
mat c(a.size(),vec(b[0].size()));
for(int i=0; i<a.size(); i++)
{
for(int k=0; k<b.size(); k++)
{
for(int j=0; j<b[0].size(); j++)
c[i][j]=(c[i][j]+a[i][k]*b[k][j])%mod;
}
}
return c;
}
mat solve_pow(mat a,int n)//快速幂
{
mat b(a.size(),vec(a.size()));
for(int i=0; i<a.size(); i++)
b[i][i]=1;
while(n>0)
{
if(n&1)
b=mul(b,a);
a=mul(a,a);
n>>=1;
}
return b;
}
//--------------以上,快速幂模板-----------
int main()
{
cin>>t;
while(t--)
{
cin>>n>>m;
getchar();
mat G(30,vec(30));
for(int i=1; i<=n; i++)//建图
{
for(int j=1; j<=m; j++)
{
int x1,y1,x2,y2,x3,y3,x4,y4;
scanf("((%d,%d),(%d,%d),(%d,%d),(%d,%d))",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4);
getchar();
//printf("((%d,%d),(%d,%d),(%d,%d),(%d,%d))\n",x1,y1,x2,y2,x3,y3,x4,y4);
if((i-1)*m+j==n*m)
continue;
G[(i-1)*m+j][(x1-1)*m+y1]=1;//这里涉及到离散化
G[(i-1)*m+j][(x2-1)*m+y2]=1;
G[(i-1)*m+j][(x3-1)*m+y3]=1;
G[(i-1)*m+j][(x4-1)*m+y4]=1;
//G[(i-1)*m+j][(i-1)*m+j]=1;
}
}
cin>>q;
while(q--)
{
int time;
cin>>time;
mat a=solve_pow(G,time);//快速幂运算
if(a[1][n*m]==0)//如果终点是0就是到不了的
{
cout<<"False"<<endl;
continue;
}
else
{
int flag=0;
for(int i=1; i<n*m; i++)//如果仅有那个点是1,那么就是true,否则就是maybe
{
if(a[1][i])
{
flag=1;
break;
}
}
if(flag==0)
cout<<"True"<<endl;
else cout<<"Maybe"<<endl;
}
}
cout<<endl;
}
return 0;
}