UVA 11149 Power of Matrix 构造矩阵

题目大意:意思就是让求A(A是矩阵)+A2+A3+A4+A5+A6+······+AK,其中矩阵范围n<=40,k<=1000000。

解题思路:由于k的取值范围很大,所以很自然地想到了二分法,用递归逐步将k二分(公式:A+A2+A3+A4+A5+A= A+A2+A+ A3(A+A2+A3)),

  这种方法只需要注意k是奇数的情况就可以了。

  最坑的是第二种方法,根据矩阵的性质可以构造出来一个子矩阵,假如有矩阵B=|A  E| ,那么B=|AK   E+ A+A2+A3+A4+A5+A6+······+AK|

|0  E|                |0          E                                         |

  呵呵········,这种方法wa了好多次,我曾经开始怀疑线性代数老师是不是讲错了。最后在T巨的提醒下发现 然后还有结束标志,还有每个实例后面都有一个换行。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 using namespace std;
 6 const int maxn = 85;
 7 int  n;
 8 struct mat
 9 {
10     int  p[maxn][maxn];
11 };
12 mat mul (mat a, mat b)
13 {
14     int i, j, k, m;
15     m = n * 2;
16     mat c;
17     memset (c.p, 0, sizeof(c.p));
18     for (i=0; i<m; i++)
19         for (j=0; j<m; j++)
20         {
21             for (k=0; k<m; k++)
22                 c.p[i][j] += a.p[i][k] * b.p[k][j];
23             c.p[i][j] = c.p[i][j] % 10;
24         }
25     return c;
26 }
27
28 mat pow (int n, mat a, mat b)
29 {
30     while (n)
31     {
32         if (n % 2)
33         {
34             b = mul (b, a);
35         }
36         n /= 2;
37         a = mul (a, a);
38     }
39     return b;
40 }
41
42 int main ()
43 {
44     int k;
45     while (scanf ("%d %d", &n, &k))
46     {
47         if (!n)
48             break;
49         mat a, b;
50         memset (b.p, 0, sizeof(b.p));
51         memset (a.p, 0, sizeof(a.p));
52
53         for (int i=0; i<n; i++)
54             for (int j=0; j<n; j++)
55             {
56                 scanf ("%d", &a.p[i][j]);
57                 a.p[i][j] = a.p[i][j] % 10;
58             }
59
60         for (int i=0; i<n; i++)//构造矩阵,使a矩阵的右上,右下成为单位矩阵,把b也初始化为单位矩阵
61             a.p[i][i+n] = a.p[i+n][i+n] = b.p[i][i] = b.p[i+n][i+n] = 1;
62
63         b = pow (k+1, a, b);
64         for (int i=0; i<n; i++)
65             for (int j=0; j<n; j++)
66             {
67                 if (i == j)//在b右上角的那个矩阵减去一个单位矩阵
68                     {
69                         b.p[i][j+n] --;
70                         if (b.p[i][j+n] < 0)//防止出现末尾是零,减去单位矩阵是-1的情况。
71                             b.p[i][j+n] = 9;
72                     }
73                 if (j == n-1)
74                     printf ("%d\n", b.p[i][j+n]);
75                 else
76                     printf ("%d ", b.p[i][j+n]);
77             }
78             printf ("\n");
79     }
80     return 0;
81 }
时间: 2024-08-09 07:49:50

UVA 11149 Power of Matrix 构造矩阵的相关文章

UVA - 11149 Power of Matrix(矩阵倍增)

题意:已知N*N的矩阵A,输出矩阵A + A2 + A3 + . . . + Ak,每个元素只输出最后一个数字. 分析: A + A2 + A3 + . . . + An可整理为下式, 从而可以用log2(n)的复杂度算出结果. 注意:输入时把矩阵A的每个元素对10取余,因为若不处理,会导致k为1的时候结果出错. #include<cstdio> #include<cstring> #include<cstdlib> #include<cctype> #in

UVA 11149 - Power of Matrix(矩阵倍增)

UVA 11149 - Power of Matrix 题目链接 题意:给定一个n*n的矩阵A和k,求∑kiAi 思路:利用倍增去搞,∑kiAi=(1+Ak/2)∑k/2iAi,不断二分即可 代码: #include <cstdio> #include <cstring> const int N = 45; int n, k; struct mat { int v[N][N]; mat() {memset(v, 0, sizeof(v));} mat operator * (mat

Uva 11149 - Power of Matrix ( 矩阵快速幂 )

Uva 11149 -Power of Matrix ( 矩阵快速幂 ) #include <cstdio> #include <cstring> #define CLR( a, b ) memset( a, b, sizeof(a) ) #define MOD 10 #define MAX_SIZE 40 struct Mat { int r, c; int mat[MAX_SIZE][MAX_SIZE]; Mat( int _r = 0 , int _c = 0 ) { CLR

UVa 11149 Power of Matrix (矩阵快速幂,倍增法或构造矩阵)

题意:求A + A^2 + A^3 + ... + A^m. 析:主要是两种方式,第一种是倍增法,把A + A^2 + A^3 + ... + A^m,拆成两部分,一部分是(E + A^(m/2))(A + A^2 + A^3 + ... + A^(m/2)),然后依次计算下去,就可以分解,logn的复杂度分解,注意要分奇偶. 另一种是直接构造矩阵,,然后就可以用辞阵快速幂计算了,注意要用分块矩阵的乘法. 代码如下: 倍增法: #pragma comment(linker, "/STACK:10

UVa 11149 - Power of Matrix

题目:一直方阵A,计算A + A^2 + A^3 + ... + A^n. 分析:分治,快速模幂. 设F(n)= A + A^2 + A^3 + ... + A^n则有: F(n)= F(n/2)+ F(n/2)* A^(n/2)+ R:(n为奇数存在R,为A^n) = F(n/2){E + A^(n/2)} + R: 利用递归和分治求解即可. 说明:读入的数据直接取模,否则会溢出╮(╯▽╰)╭. #include <algorithm> #include <iostream> #

hdu 5015 233 Matrix(构造矩阵)

http://acm.hdu.edu.cn/showproblem.php?pid=5015 因为是个二维的递推式,当时没有想到可以这样构造矩阵.从列上看,当前这一列都是由前一列递推得到.根据这一点来构造矩阵.令b[i]代表第i列,是一个(n+2)*1的矩阵,即b[1] = [1,233......],之所以在加了两行,是要从前一个矩阵b[i-1]得到b[i]中的第二个数2333...,再构造一个转换矩阵a,它是一个(n+2)*(n+2)的矩阵,那么a^(m-1) * b就是第m列. /* a矩

UVA 11551 - Experienced Endeavour(构造矩阵-水题)

题意:求一列序列的经过r次变化后的新序列,这些变化都是旧序列的某些已给位置的和产生新的项 思路:好水,直接构造01矩阵 //Accepted 45 ms C++ 4.8.2 1442 #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int mod= 1000; int num[55]; int res[55

构造矩阵解决问题 【nyoj299 Matrix Power Series】

矩阵的又一个新用法,构造矩阵进行快速幂. 比如拿 nyoj299 Matrix Power Series 来说 给出这样一个递推式: S = A + A2 + A3 + - + Ak. 让你求s,A是一个矩阵,而k非常大.怎么办呢? 推理发现:Fn = A + A*F(n-1) 然后我们可以构造矩阵: (Fn ,1 ) =  (Fn-1 ,1) * (A,0.A,1) = (F1 , 1) * (A,0.A,1)^K-1 那么我们就可以用一个矩阵快速幂了. 下面是模板题目的代码: #includ

构造矩阵解决这个问题 【nyoj299 Matrix Power Series】

矩阵的又一个新使用方法,构造矩阵进行高速幂. 比方拿 nyoj299 Matrix Power Series 来说 给出这样一个递推式: S = A + A2 + A3 + - + Ak. 让你求s.A是一个矩阵,而k很大. 怎么办呢? 推理发现:Fn = A + A*F(n-1) 然后我们能够构造矩阵: (Fn .1 ) =  (Fn-1 ,1) * (A.0. A,1) = (F1 , 1) * (A,0. A,1)^K-1 那么我们就能够用一个矩阵高速幂了. 以下是模板题目的代码: #in