矩阵快速幂: 网易2017实习生编程题 魔力手环

描述:
小易拥有一个拥有魔力的手环上面有n个数字(构成一个环),当这个魔力手环每次使用魔力的时候就会发生一种奇特的变化:每个数字会变成自己跟后面一个数字的和(最后一个数字的后面一个数字是第一个),一旦某个位置的数字大于等于100就马上对100取模(比如某个位置变为103,就会自动变为3).现在给出这个魔力手环的构成,请你计算出使用k次魔力之后魔力手环的状态。
输入描述:
输入数据包括两行:
第一行为两个整数n(2 ≤ n ≤ 50)和k(1 ≤ k ≤ 2000000000),以空格分隔
第二行为魔力手环初始的n个数,以空格分隔。范围都在0至99.
输出描述:
输出魔力手环使用k次之后的状态,以空格分隔,行末无空格。
输入例子:
3 2
1 2 3
输出例子:
8 9 7

分析:
由于题目中的求值非常有规律,数字成环,且当前数字等于当前数字加上后面的一个数字,自然就可以联想到构造矩阵,而且看到操作次数那么大,肯定要么找规律,要么快速幂,然后我打表并没有发现什么规律,所以矩阵快速幂。

#include
using namespace std;
vector<vector<int> > mul(vector<vector<int> >a,vector<vector<int> >b)
{
    int m=a.size(),n=a[0].size(),k=b[0].size();
    vector<vector<int> > res(m,vector<int>(k,0));
    for(int i=0;ifor(int j=0;jfor(int f=0;f100;
    return res;
}
vector<vector<int> > matrix_pow(vector<vector<int> > matrix,int k)
{
    int n=matrix.size();
    vector<vector<int> > mm(n,vector<int>(n,0));
    for(int i=0;i1;

    while(k){
        if(k&1)
        mm = mul(matrix,mm);
        matrix = mul(matrix,matrix);
        k>>=1;
    }
    return mm;
}
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    vector<vector<int> > num;
    vector<int> t;
    int tmp;
    for(int i=0;iscanf("%d",&tmp);
        t.push_back(tmp);
    }
    num.push_back(t);
    vector<vector<int> > matrix(n,vector<int>(n,0));
    for(int i=0;i1;
        matrix[(i+1)%n][i]=1;
    }

    vector<vector<int> > mm = matrix_pow(matrix,k);
    vector<vector<int> > ans = mul(num,mm);
    printf("%d",ans[0][0]);
    for(int i=1;i0].size();i++)
        printf(" %d",ans[0][i]);
    puts("");

    return 0;
}

你可能感兴趣的:(math)