POJ 3734 Blocks 生成函数及矩阵的解法

来源:互联网 发布:淘宝店铺装修图 编辑:程序博客网 时间:2024/06/05 18:00

http://poj.org/problem?id=3734

无意中看到这题然后网上看了题解,正好可以用生成函数解决,也看到有用矩阵解决的,所以学习了用两种方法解决该问题。网上也有很多人建议用费马定理的,这里就不一一实现。

(1)用生成函数推出其公式,同斐波那契的通项式类似,推出其规律,然后编程就很容易。 

#include <iostream>const int MOD = 10007;int tmod_n(int x, int n){int ans = 1;while(n > 0){if(n%2 == 1){ans = ans*x%MOD;}x = x*x%MOD;n /= 2;}return ans;}int getAns(int k){if(0 == k){return 0;}if(1 == k){return 2;}int ans = tmod_n(4, k-1) + tmod_n(2, k-1);ans %= MOD;return ans;}int main(){int t = 0;std::cin>>t;while(t--){int x;std::cin>>x;std::cout<<getAns(x)<<std::endl;}return 0;}

(2)找出其关系式,不用推其通项式,直接用矩阵实现,发现这样推的过程少很多,当然程序效率与上述相比也差很多,但我觉的矩阵给我们提供了一种很好解决问题的思路。下面的代码没经过仔细推敲,主要是学习式的应用一些知识。

//poj 3734 矩阵实现//ans[i+1] = ans[i]*2 + 2*4^(i-2); i > 2#include <iostream>const int MOD = 10007;class Matrix{public:Matrix(int r, int c);Matrix(const Matrix& m);Matrix& operator=(const Matrix&);~Matrix();public:int row, cross;int** mat;};inline Matrix::Matrix(int r, int c):row(r), cross(c){mat = new int*[r];for(int i = 0; i < r; i++){mat[i] = new int[c];}}Matrix::Matrix(const Matrix& m){row = m.row;cross = m.cross;mat = new int*[row];int r, c;for(r = 0; r < row; r++){mat[r] = new int[cross];for(c = 0; c < cross; c++){mat[r][c] = m.mat[r][c];}}}Matrix& Matrix::operator =(const Matrix& m){if(this == &m){return *this;}int r, c;for(r = 0; r < row; r++){delete []mat[r];}row = m.row;cross = m.cross;for(r = 0; r < row; r++){mat[r] = new int[cross];for(c = 0; c < cross; c++){mat[r][c] = m.mat[r][c];}}return *this;}Matrix::~Matrix(){int r;for(r = 0; r < row; r++){delete []mat[r];}}Matrix multMatrix(Matrix& mx, Matrix& my){if(mx.cross != my.row){Matrix mtmp(0, 0);return mtmp;}Matrix tmp(mx.row, my.cross);int r, c, t;for(r = 0; r < tmp.row; r++){for(c = 0; c < tmp.cross; c++){tmp.mat[r][c] = 0;for(t = 0; t < mx.cross; t++){tmp.mat[r][c] += mx.mat[r][t]*my.mat[t][c];}tmp.mat[r][c] %= MOD;  ///////=========}}return tmp;}int modMatrix(int n, Matrix m, int val){Matrix orl(2, 1);orl.mat[0][0] = val; orl.mat[1][0] = 2;Matrix tmp(2, 2);tmp.mat[0][0] = 1; tmp.mat[0][1] = 0;tmp.mat[1][0] = 0; tmp.mat[1][1] = 1;while(n > 0){if(n%2==1){tmp = multMatrix(tmp, m);}m = multMatrix(m, m);n /= 2;}orl = multMatrix(tmp, orl);return orl.mat[0][0];}int getAns(int n){if(0 == n) return 0;if(1 == n) return 2;Matrix m(2, 2);m.mat[0][0] = 2; m.mat[0][1] = 1;m.mat[1][0] = 0; m.mat[1][1] = 4;return modMatrix(n-1, m, 2)%MOD;}int main(){int t;std::cin>>t;while(t--){int n;std::cin>>n;std::cout<<getAns(n)<<std::endl;}return 0;}