zoukankan      html  css  js  c++  java
  • 矩阵经典题目四:送给圣诞夜的礼品(使用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("
    ");
                else printf(" ");
            }
        }
        return 0;
    }
    



  • 相关阅读:
    正则表达式周二挑战赛 第七周
    [译]视区百分比,canvas.toBlob()以及WebRTC
    [译]因扩展Object.prototype而引发Object.defineProperty不可用的一个问题
    [译]JavaScript需要类吗?
    [译]JavaScript中几种愚蠢的写法
    [译]JavaScript中对象的属性
    JavaScript:数组的length属性
    [译]JavaScript中的变量声明:你可以打破的三条规则
    [译]ES6:JavaScript中将会有的几个新东西
    [译]ECMAScript 6中的集合类型,第三部分:WeakMap
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/6745273.html
Copyright © 2011-2022 走看看