[编程题] 魔力手环
时间限制:1秒
空间限制:32768K
小易拥有一个拥有魔力的手环上面有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
解题思路:本题使用暴力的方式,每次进行处理,处理k次,会超时
1 #include <iostream> 2 3 using namespace std; 4 5 int main() 6 { 7 int n; 8 int k; 9 while(cin>>n>>k) 10 { 11 int a[n]; 12 for(int i=0;i<n;i++) 13 { 14 cin>>a[i]; 15 } 16 for(int i=0;i<k;i++) 17 { 18 int tmp = a[0]; 19 int j=0; 20 for(;j<n-1;j++) 21 { 22 a[j] = (a[j] + a[j+1])%100; 23 } 24 a[j] = (a[j]+tmp)%100; 25 } 26 int i=0; 27 for(;i<n-1;i++) 28 { 29 cout<<a[i]<<" "; 30 } 31 cout<<a[i]; 32 33 } 34 return 0; 35 }
以上代码只通过60%
正确做法:思路:n个数的环进行移动相加,考虑到矩阵行、列变换可以完成这种移动和相加,于是构造出快速幂矩阵,快速幂矩阵M和原矩阵S相乘得到一次移动的结果,那么F(n+1) = M^n*S(这里的幂和乘法是矩阵的运算),很容易得到如下递推示例:
[[1 1 0] [0 1 1] [1 0 1]]*[[a][b][c]] = [[a+b][b+c][c+a]], 如此,已经确定了快速幂矩阵M,那么就要考虑如何相乘得到最快的幂求解速度。
[[1 1 0] [0 1 1] [1 0 1]]*[[a][b][c]] = [[a+b][b+c][c+a]], 如此,已经确定了快速幂矩阵M,那么就要考虑如何相乘得到最快的幂求解速度。
1 #include <iostream> 2 #include<cstring> 3 using namespace std; 4 5 int main() 6 { 7 int n,k; 8 cin >> n >> k; 9 int d[n];//存放结果 10 for(int i=0;i<n;++i) 11 { 12 cin >> d[i]; 13 } 14 //构造快速幂矩阵 15 int Mul[n][n]; 16 for(int i=0;i<n-1;++i) 17 { 18 fill(Mul[i],Mul[i]+n,0); 19 Mul[i][i] = 1; 20 Mul[i][i+1] = 1; 21 } 22 fill(Mul[n-1],Mul[n-1]+n,0); 23 Mul[n-1][0] = 1; 24 Mul[n-1][n-1] = 1; 25 //转化为2进制,进行二分搜索 26 while(k) 27 { 28 if(k&1) 29 { 30 int temp[n]; 31 fill(temp, temp+n, 0); 32 for(int i=0;i<n;++i) 33 { 34 for(int j=0;j<n;++j) 35 { 36 temp[i] += (Mul[i][j]*d[j]); 37 temp[i] = temp[i]%100; 38 } 39 } 40 memcpy(d, temp, sizeof(d)); 41 } 42 k = k>>1; 43 int temp[n][n]; 44 for(int i=0;i<n;++i) 45 { 46 fill(temp[i],temp[i]+n,0); 47 } 48 for(int i=0;i<n;++i) 49 { 50 for(int j=0;j<n;++j) 51 { 52 for(int k=0;k<n;++k) 53 { 54 temp[i][j]+=Mul[i][k]*Mul[k][j];//二维矩阵相乘 55 } 56 temp[i][j] %= 100;//快速幂取余中,a^k % c = (a % c)^k % c 57 } 58 } 59 for(int i=0;i<n;++i) 60 { 61 memcpy(Mul[i],temp[i],sizeof(Mul[i])); 62 } 63 } 64 //输出结果 65 for(int i=0;i<n-1;++i) 66 { 67 cout << d[i] <<" "; 68 } 69 cout << d[n-1] << endl; 70 return 0; 71 }