试题编号: | 201512-5 |
试题名称: | 矩阵 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: |
问题描述
创造一个世界只需要定义一个初状态和状态转移规则。
宏观世界的物体运动规律始终跟物体当前的状态有关,也就是说只要知道物体足够多的状态信息,例如位置、速度等,我们就能知道物体之后任意时刻的状态。 现在小M创造了一个简化的世界。 这个世界中,时间是离散的,物理规律是线性的:世界的初始状态可以用一个m维向量b (0)表示,状态的转移方式用m×m的矩阵A表示。 若已知这个世界当前的状态是b,那么下一时刻就等于b左乘状态转移矩阵A,即Ab。 这个世界中,物体的状态也是离散的,也就是说可以用整数表示。再进一步,整数都可以用二进制编码拆分为有限位0和1。因此,这里的矩阵A和向量b的每个元素都是0或1,矩阵乘法中的加法运算视为异或运算(xor),乘法运算视为与运算(and)。 具体地,设矩阵A第i行第j列的元素为a i , j,向量b的第i个元素为b i。那么乘法Ab所得的第k个元素为 (a k ,1 and b 1) xor (a k ,2 and b 2) xor ⋯ xor (a k ,m and b m) 矩阵和矩阵的乘法也有类似的表达。 小M发现,这样的矩阵运算也有乘法结合律,例如有A(Ab)=(AA)b=A 2b。 为了保证自己创造的世界维度不轻易下降,小M保证了矩阵A可逆,也就是说存在一个矩阵A -1,使得对任意向量d,都有A -1Ad=d。 小M想了解自己创造的世界是否合理,他希望知道这个世界在不同时刻的状态。 具体地,小M有n组询问,每组询问会给出一个非负整数k,小M希望你帮他求出A kb。
输入格式
输入第一行包含一个整数m,表示矩阵和向量的规模。
接下来m行,每行包含一个长度为m的01串,表示矩阵A。 接下来一行,包含一个长度为m的01串,表示初始向量b (0)。(b (0)是列向量,这里表示它的转置) 注意:01串两个相邻的数字之间均没有空格。 接下来一行,包含一个正整数n,表示询问的个数。 最后n行,每行包含一个非负整数k,表示询问A kb (0)。 注意:k可能为0,此时是求A 0b (0) =b (0)。
输出格式
输出n行,每行包含一个01串,表示对应询问中A
kb
(0)的结果。
注意:01串两个相邻的数字之间不要输出空格。
样例输入
3
110 011 111 101 10 0 2 3 14 1 1325 6 124124 151 12312
样例输出
101
010 111 101 110 010 100 101 001 100
评测用例规模与约定
本题使用10个评测用例来测试你的程序。
对于评测用例1,m = 10,n = 100,k ≤ 10 3。 对于评测用例2,m = 10,n = 100,k ≤ 10 4。 对于评测用例3,m = 30,n = 100,k ≤ 10 5。 对于评测用例4,m = 180,n = 100,k ≤ 10 5。 对于评测用例5,m = 10,n = 100,k ≤ 10 9。 对于评测用例6,m = 30,n = 100,k ≤ 10 9。 对于评测用例7,m = 180,n = 100,k ≤ 10 9。 对于评测用例8,m = 600,n = 100,k ≤ 10 9。 对于评测用例9,m = 800,n = 100,k ≤ 10 9。 对于评测用例10,m = 1000,n = 100,k ≤ 10 9。 |
开始很菜的想法:
1 //ccf-矩阵 mat^k*b0 2 #include<iostream> 3 #include<cmath> 4 //#include<vector> 5 using namespace std; 6 int main() 7 { 8 int m, n, i, j; cin >> m; 9 char ch[1000]; bool*temp = 0; 10 //vector<int>ma; 11 //vector<vector<int>> mat; 12 bool**mat = new bool*[m]; 13 for (i = 0; i < m; i++) 14 mat[i] = new bool[m]; 15 bool b0[1000]; 16 bool ans[1000]; 17 unsigned k; 18 for (i = 0; i<m; i++) 19 { 20 cin >> ch;//01串之间没有空格 21 for (j = 0; j<m; j++) 22 mat[i][j] = ch[j] - '0'; 23 } 24 cin >> ch; 25 for (i = 0; i<m; i++) 26 { 27 b0[i] = ch[i] - '0'; 28 //ans[i]=ch[i]; 29 } 30 cin >> n; 31 while (n--) 32 { 33 cin >> k; 34 if (k) 35 { 36 for (i = 0; i < m; i++) 37 ans[i] = 0; 38 for (i = 0; i < m; i++) 39 for (j = 0; j < m; j++) 40 ans[i] ^= b0[j] & mat[i][j]; 41 if (--k) 42 temp = new bool[m]; 43 while (k--) 44 { 45 for (i = 0; i < m; i++) 46 { 47 temp[i] = ans[i]; 48 ans[i] = 0; 49 } 50 for (i = 0; i < m; i++) 51 for (j = 0; j < m; j++) 52 ans[i] ^= temp[j]& mat[i][j]; 53 } 54 for (i = 0; i < m; i++) 55 cout << ans[i]; 56 cout << endl; 57 58 } 59 else 60 { 61 for (i = 0; i<m; i++) 62 cout << b0[i]; 63 cout << endl; 64 } 65 } 66 for (i = 0; i < m; i++) 67 delete[]mat[i]; 68 delete[]mat; 69 return 0; 70 }
结果正确,但是超时pass