zoukankan      html  css  js  c++  java
  • HDU 1005 Number Sequence

    题目链接:HDU 1005 Number Sequence

    题目大意:
    (f(1)=1,f(2)=1,f(n)=(A*f(n-1)+B*f(n-2))\%7)
    给出(A)(B)(N)求出(f(N))

    题解:
    可以通过找规律的方法解决这道题,由于(f(n))要模(7),所以只有(0)~(6)七种情况,而(f(n))(f(n-1))的组合情况就只有(7 imes7=49)种,只要找到(f(n))(f(n-1))都是(1)的情况,就可以知道这个数列循环的周期。

    为了训练矩阵快速幂,所以选择用矩阵快速幂来做这道题。

    由递推公式构建矩阵:

    [ left( egin{matrix} f(n-1) & f(n-2) end{matrix} ight) imes left( egin{matrix} a & 1 \ b & 0 end{matrix} ight)= left( egin{matrix} f(n) & f(n-1) end{matrix} ight) ]

    通过矩阵快速幂和矩阵乘法得到(f(n))

    #include <iostream>
    #include <cstring>
    using namespace std;
    #define ms(a, b) memset(a, b, sizeof(a))
    #define io_speed_up ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define N 2
    
    const int mod = 7;
    int a, b, n;
    struct Matrix {
    	int num[N][N];
    };
    
    Matrix multi(Matrix a, Matrix b) {
    	Matrix c;
    	ms(c.num, 0);
    	for (int i = 0; i < N; ++i) {
    		for (int j = 0; j < N; ++j) {
    			for (int k = 0; k < N; ++k) {
    				c.num[i][j] += a.num[i][k] * b.num[k][j];
    				c.num[i][j] %= mod;
    			}
    		}
    	}
    	return c;
    }
    
    Matrix fastPow(Matrix x, int k) {
    	Matrix res;
    	ms(res.num, 0);
    	for (int i = 0; i < N; ++i) {
    		res.num[i][i] = 1;
    	}
    	while (k) {
    		if (k & 1) {
    			res = multi(res, x);
    		}
    		x = multi(x, x);
    		k >>= 1;
    	}
    	return res;
    }
    
    int main() {
    	io_speed_up;
    	while (cin >> a >> b >> n) {
    		if (!a && !b && !n) {
    			break;
    		}
    		Matrix temp;
    		temp.num[0][0] = a;
    		temp.num[0][1] = 1;
    		temp.num[1][0] = b;
    		temp.num[1][1] = 0;
    		temp = fastPow(temp, n - 1);
    		cout << (temp.num[0][1] + temp.num[1][1]) % mod << endl;
    	}
    	return 0;
    }
    

    P.S. 如果将矩阵快速幂代码写成如下,会不知为何而超时。

    		temp = fastPow(temp, n - 2);
    		cout << (temp.num[0][0] + temp.num[1][0]) % mod << endl;
    
  • 相关阅读:
    【消息队列MQ】各类MQ比较
    MySql查询功能梳理
    头条日常实习生面经 2018.11.28
    排序算法 JavaScript
    浅谈二分查找 JavaScript
    LeetCode17.电话号码的字母组合 JavaScript
    LeetCode16.最接近的三数之和 JavaScript
    LeetCode15.三数之和 JavaScript
    LeetCode14.最长公共前缀 JavaScript
    LeetCode13.罗马数字转整数 JavaScript
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/13818369.html
Copyright © 2011-2022 走看看