poj3734 Blocks
Posted yzxverygood
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj3734 Blocks相关的知识,希望对你有一定的参考价值。
题目大意
有n个方块,有1,2,3,4四种颜色对其进行染色,求1,2颜色的方块个数均为偶数的方案数对10007取模的值。
分析
我们假设1表示这个颜色个数是奇数,0表示是偶数,所以对于所有状态我们可以分为四种,每种对应一个二元组 ,二元组的第一项表示颜色1,第二项表示颜色2,这四种分别是(1,1),(1,0),(0,1),(0,0)。但是我们不难发现(1,0)和(0,1)这两种状态可以合为一种,所以我们可以推出:
(1,1) = 2*(1,1) + (1,0)
(1,0) = (1,1) + 2*(1,0) + 2*(0,0)
(0,0) = 2*(0,0) + (1,0)
我们通过这个便可以得到转移矩阵了。详见代码。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
const int mod = 10007;
struct mat {
int g[5][5];
};
inline mat operator * (mat a,mat b){
mat c;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++){
int x=0;
for(int k=1;k<=3;k++)
x=(x+a.g[i][k]*b.g[k][j]%mod)%mod;
c.g[i][j]=x;
}
return c;
}
inline int pw(int p){
mat res,a;
a.g[1][1]=a.g[2][1]=a.g[2][2]=a.g[2][3]=a.g[3][3]=2;
a.g[1][2]=a.g[3][2]=1;
a.g[1][3]=a.g[3][1]=0;
res=a;
while(p){
if(p&1)res=res*a;
a=a*a;
p>>=1;
}
return res.g[3][3];
}
int main(){
int n,t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
printf("%d
",pw(n-1));
}
return 0;
}
以上是关于poj3734 Blocks的主要内容,如果未能解决你的问题,请参考以下文章