骨牌覆盖问题三(k*N棋盘覆盖)

骨牌覆盖问题一
骨牌覆盖问题二
骨牌覆盖问题三

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<set>
#include<queue>
#include<stack>
#include<map>
using namespace std;
#define mod 12357
int n,m;
struct Matrix{
    int a[1<<7][1<<7];
    Matrix(){
        memset(a,0,sizeof(a));
        for(int i=0;i<(1<<m);++i) a[i][i]=1;
    }
    void init(){
        memset(a,0,sizeof(a));
    }
};

Matrix operator*(Matrix a,Matrix b)
{
    Matrix c;
    for(int i=0;i<(1<<m);++i)
        for(int j=0;j<(1<<m);++j)
        {
            c.a[i][j]=0;
            for(int k=0;k<(1<<m);++k)
                c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%mod)%mod;
        }
    return c;
}

Matrix POW(Matrix a,int n)
{
    Matrix c;
    while(n)
    {
        if(n&1) c=c*a;
        a=a*a;
        n>>=1;
    }
    return c;
}

Matrix mat;

void dfs(int now,int pre,int dep)
{
    if(dep>m) return;
    if(dep==m){
        mat.a[pre][now]=1;
        return;
    }
    dfs(now<<1,pre<<1|1,dep+1);
    dfs(now<<1|1,pre<<1,dep+1);
    dfs(now<<2|3,pre<<2|3,dep+2);
}

int main()
{
    while(~scanf("%d%d",&n,&m)&&(n+m))
    {
        if(m>n) swap(n,m);
        mat.init();
        dfs(0,0,0);
        mat=POW(mat,n);
        printf("%d\n",mat.a[(1<<m)-1][(1<<m)-1]);
    }
    return 0;
}

你可能感兴趣的:(骨牌覆盖问题三(k*N棋盘覆盖))