首页 > 代码库 > 矩阵经典题目四:送给圣诞夜的礼品(使用m个置换实现对序列的转变)
矩阵经典题目四:送给圣诞夜的礼品(使用m个置换实现对序列的转变)
https://vijos.org/p/1049
给出一个序列,含n个数。然后是m个置换,求对初始序列依次进行k次置换,求最后的序列。
先看一个置换,把置换表示成矩阵的形式,然后将m个置换乘起来。那么初始序列首先执行这个置换k/m次,然后顺次执行前k%m个置换,最后乘上初始矩阵。
最后注意矩阵乘法的顺序,A*B != B*A。
#include <stdio.h> #include <iostream> #include <map> #include <set> #include <list> #include <stack> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #include <algorithm> #define LL long long #define _LL __int64 #define eps 1e-12 #define PI acos(-1.0) #define C 240 #define S 20 using namespace std; const int maxn = 110; struct matrix { int mat[maxn][maxn]; int n,m; void init() { memset(mat,0,sizeof(mat)); for(int i = 1; i <= 105; i++) { mat[i][i] = 1; } } }M[11]; //将每一个置换表示出来。 int n,m; matrix mul(matrix a, matrix b) { matrix ans; memset(ans.mat,0,sizeof(ans.mat)); ans.n = a.n; ans.m = b.m; for(int i = 1; i <= a.n ; i++) { for(int k = 1; k <= a.m; k++) { if(a.mat[i][k] == 0) continue; for(int j = 1; j <= b.m; j++) ans.mat[i][j] += a.mat[i][k]*b.mat[k][j]; } } return ans; } matrix pow(matrix a, int n) { matrix ans; ans.n = a.n; ans.m = a.m; ans.init(); while(n) { if(n&1) ans = mul(ans,a); a = mul(a,a); n >>= 1; } return ans; } int main() { int num,k,z; while(~scanf("%d %d %d",&n,&m,&k)) { matrix a,b; a.init(); a.m = a.n = n; b.n = n; b.m = 1; for(int i = 1; i <= n; i++) b.mat[i][1] = i; for(int i = 1; i <= m; i++) { memset(M[i].mat,0,sizeof(M[i].mat)); M[i].m = M[i].n = n; for(int j = 1; j <= n; j++) { scanf("%d",&num); M[i].mat[j][num] = 1; } a = mul(M[i],a); //注意相乘的顺序 } z = k/m; k = k%m; a = pow(a,z); for(int i = 1; i <= k; i++) a = mul(M[i],a);//注意相乘的顺序 a = mul(a,b); for(int i = 1; i <= n; i++) { printf("%d",a.mat[i][1]); if(i == n) printf("\n"); else printf(" "); } } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。