zju 3497 Mistwald(矩阵乘法)

省赛的时候怪自己太弱,什么都不会,而如今依然……

重操旧时废业。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define M 26
struct matrix{
	bool a[M][M];
	int n;
//重载矩阵乘法运算符
    friend matrix operator* (matrix a,matrix b){
		matrix c;
		c.n=a.n;
		for(int i=0;i<a.n;i++){
			for(int j=0;j<a.n;j++){
				c.a[i][j]=false;
				for(int k=0;k<a.n;k++)
					c.a[i][j]|=(a.a[i][k]*b.a[k][j]);
			}
		}
		return c;
	}
};
matrix e;
//初始化单位矩阵
void Init(){
	memset(e.a,0,sizeof(e.a));
	for(int i=0;i<M;i++)
		e.a[i][i]=true;
}
//快速矩阵乘法
matrix Power(matrix a,int p){
	matrix b=e;
	b.n=a.n;
	for(;p;p>>=1,a=a*a){
		if(p&1)
			b=b*a;
	}
	return b;
}
int main(){
	Init();
	int t;
	scanf("%d",&t);
	while(t--){
		int h,w,i,j,k,s[8],n;
		char str[M*M];
		matrix ans;
		scanf("%d%d",&h,&w);
		ans.n=h*w;
		//  (1,1) -->(N,M) 即为 0 ---> h*w-1 可达
		memset(ans.a,false,sizeof(ans.a));
		for(i=0;i<h;i++){
			for(j=0;j<w;j++){
				scanf("%s",str);
				sscanf(str,"((%d,%d),(%d,%d),(%d,%d),(%d,%d))",
					&s[0],&s[1],&s[2],&s[3],&s[4],&s[5],&s[6],&s[7]);
				for(k=0;k<8;k+=2)
					ans.a[w*i+j][(s[k]-1)*w+s[k+1]-1]=true;
			}
		}
		//因为当到达最后一点时立即被传送出去,所以,最后点所到之处全部置为不可到达。
		for(i=0;i<ans.n;i++)
			ans.a[ans.n-1][i]=false;
		scanf("%d",&n);
		while(n--){
			int p;
			scanf("%d",&p);
			matrix res;
			res=Power(ans,p);
			if(!res.a[0][res.n-1]){ //如果最后一点不可到达,返回False
				puts("False");
				continue;
			}
			for(i=0;i<res.n;i++)
				if(res.a[0][i])
					break; 
				puts(res.n-1==i?"True":"Maybe"); 
/* 已经能够达到,若仅有最后点能到,不能达到其它点,则一定True,
   否则就是可以到达其它点,Maybe。
*/
		}
		putchar('\n');
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值