记录编号 162150 评测结果 AAAAAAAAAA
题目名称 [TJOI 2015] 棋盘 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.045 s
提交时间 2015-05-14 15:08:46 内存使用 0.32 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef unsigned int UI;
class Matrix{
public:
	int n,m;
	UI s[65][65];
	Matrix(){memset(s,0,sizeof(s));}
	void idt(int x){
		memset(s,0,sizeof(s));
		n=m=x;
		for(int i=0;i<n;i++) s[i][i]=1;
	}
};
Matrix operator * (const Matrix &a,const Matrix &b){
	Matrix c;
	c.n=a.n,c.m=b.m;
	for(int i=0;i<c.n;i++){
		for(int j=0;j<c.m;j++){
			c.s[i][j]=0;
			for(int k=0;k<a.m;k++){
				c.s[i][j]+=(a.s[i][k]*b.s[k][j]);
			}
		}
	}
	return c;
}
Matrix quickpow(Matrix a,int n){
	Matrix ans;
	ans.idt(a.n);
	while(n){
		if(n&1) ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
int N,M,P,K;
int fire[4][10]={0};
bool peace[65][65]={0};
int now[4][10];
bool check(int s,int t){
	for(int i=0;i<M;i++){
		now[0][i]=((s>>i)&1);
		now[1][i]=((t>>i)&1);
	}
	for(int x=0;x<2;x++){
		for(int y=0;y<M;y++){
			if(now[x][y]==1){
				for(int i=0;i<3;i++){
					for(int j=0;j<P;j++){
						if(!fire[i][j]) continue;
						int dx=i-1,dy=j-K;
						if(dx==0&&dy==0) continue;
						int nx=x+dx,ny=y+dy;
						if(0<=nx&&nx<2&&0<=ny&&ny<=M){
							if(now[nx][ny]==1) return false;
						}
					}
				}
			}
		}
	}
	return true;
}
void work(void){
	Matrix D;
	D.n=D.m=1<<M;
	for(int i=0;i<D.n;i++){
		for(int j=0;j<D.m;j++){
			//cout<<i<<" "<<j<<" "<<check(i,j)<<endl;
			D.s[i][j]=check(i,j);
		}
	}
	Matrix O;
	O.n=1,O.m=1<<M;
	O.s[0][0]=1;
	Matrix F=O*quickpow(D,N);
	UI ans=0;
	for(int i=0;i<(1<<M);i++) ans+=F.s[0][i];
	cout<<ans<<endl;
}
void read(void){
	scanf("%d%d",&N,&M);
	scanf("%d%d",&P,&K);
	for(int i=0;i<3;i++){
		for(int j=0;j<P;j++){
			scanf("%d",&fire[i][j]);
		}
	}
}
int main(){
	freopen("tjoi2015_board.in","r",stdin);
	freopen("tjoi2015_board.out","w",stdout);
	read();
	work();
	return 0;
}