题目大意:
给你一张地图,告诉你地图上每个点可以到达的4个点。
问你从起点(1,1)走p步可不可以到达终点(m,n)。
如果不能输出False,如果一定输出Yes,如果不一定(既
有别的路可走,可以走到终点也可以不走到终点)输出Maybe。
题目坑点在于到达(m,n)后就一定要走出地图,所以(m,n)
和图上所有点是不可达的。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<cstring>
#include<queue>
#include<stack>
#include<list>
using namespace std;
typedef long long ll;
typedef vector<int > vec;
typedef vector<vec > mat;
const int MOD=1000;
int m,n;
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] );
if( C[i][j]!=0 ){
C[i][j]=1;
}
}
}
}
return C;
}
mat pow(mat A,ll n1){
mat B( A.size(),vec(A.size(),0) );
for(int i=0;i<A.size();i++){
B[i][i]=1;
}
while(n1>0){
if(n1&1)B=mul(B,A);
A=mul(A,A);
n1>>=1;
}
return B;
}
int pos(int x,int y){
return (x-1)*n+y;
}
bool check( mat A ){
int flag=0;
for(int i=0;i<A.size();i++){
if( i!=A.size()-1&&A[0][i]>0 )flag=1;
}
return flag==1;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&m,&n);
mat A( m*n, vec(m*n,0) );
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
string s;
cin>>s;
vector<int > v;
if( i==m&&j==n )continue;
for(int k=0;k<s.size();k++){
if(s[k]>='0'&&s[k]<='9'){
v.push_back(s[k]-'0');
}
}
for(int k=0;k<v.size();k+=2){
A[ pos(i,j)-1 ][ pos(v[k],v[k+1])-1 ]=1;
}
}
}
int Q;
scanf("%d",&Q);
while(Q--){
ll p;
scanf("%lld",&p);
mat tmp( m*n, vec(m*n,0) );
tmp=pow( A,p );
if( tmp[ 0 ][ A.size()-1 ]==0 ){
puts("False");
}else if( !check(tmp) ){
puts("True");
}else{
puts("Maybe");
}
}
printf("\n");
}
return 0;
}
549

被折叠的 条评论
为什么被折叠?



