zoukankan      html  css  js  c++  java
  • poj 3735 Training little cats(构造矩阵)

    http://poj.org/problem?id=3735


    大致题意:

    有n仅仅猫,開始时每仅仅猫有花生0颗,现有一组操作,由以下三个中的k个操作组成:
    1. g i 给i仅仅猫一颗花生米
    2. e i 让第i仅仅猫吃掉它拥有的全部花生米

    3. s i j 将猫i与猫j的拥有的花生米交换

    现将上述一组操作循环m次后,问每仅仅猫有多少颗花生?

    非常明显,要先构造矩阵。构造一个(n+1)*(n+1)的矩阵a,初始化为单位矩阵。

    g i : a[i][n+1] += 1;

    e i : a[i][j] = 0;(1 <= j <= n+1)

    s i j : swap(a[i][k],a[j][k])(1 <= k <= n+1)

    然后矩阵高速幂就ok了。

    注意m非常大,k也不小,要用long long .


    #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;
    int n,m,k;
    
    struct matrix
    {
        LL mat[maxn][maxn];
        void init()
        {
            memset(mat,0,sizeof(mat));
            for(int i = 1; i <= n+1; i++)
                mat[i][i] = 1;
        }
    }a,b;
    
    matrix mul(matrix a, matrix b)
    {
        matrix ans;
        memset(ans.mat,0,sizeof(ans.mat));
        for(int i = 1; i <= n+1; i++)
        {
            for(int k = 1; k <= n+1; k++)
            {
                if(a.mat[i][k] == 0) continue;
                for(int j = 1; j <= n+1; j++)
                    ans.mat[i][j] += a.mat[i][k] * b.mat[k][j];
            }
        }
        return ans;
    }
    
    matrix pow(matrix a, int nn)
    {
        matrix ans;
        ans.init();
        while(nn)
        {
            if(nn&1)
                ans = mul(ans,a);
            a = mul(a,a);
            nn >>= 1;
        }
        return ans;
    }
    
    int main()
    {
        char ch[3];
        int x,y;
        while(~scanf("%d %d %d",&n,&m,&k))
        {
            if(n == 0 && m == 0 && k == 0) break;
            a.init();
            memset(b.mat,0,sizeof(b.mat));
            b.mat[n+1][1] = 1;
            while(k--)
            {
                scanf("%s",ch);
                if(ch[0] == 'g')
                {
                    scanf("%d",&x);
                    a.mat[x][n+1] += 1;
                }
                else if(ch[0] == 'e')
                {
                    scanf("%d",&x);
                    for(int i = 1; i <= n+1; i++)
                        a.mat[x][i] = 0;
                }
                else
                {
                    scanf("%d %d",&x,&y);
                    for(int i = 1; i <= n+1; i++)
                        swap(a.mat[x][i],a.mat[y][i]);
                }
            }
            a = pow(a,m);
    		matrix ans = mul(a,b);
    		for(int i = 1; i <= n; i++)
    		{
    			printf("%lld",ans.mat[i][1]);
    			if(i == n) printf("
    ");
    			else printf(" ");
    		}
        }
        return 0;
    
    }
    



  • 相关阅读:
    boost lexical_cast 字符串数字间的字面转换(学习笔记)
    Smoke Testing
    深入浅出InfoPath——手工绑定托管代码
    深入浅出InfoPath——操作InfoPath元素
    深入浅出SharePoint2010——附录:常用术语对照
    CAML语法必备
    深入浅出SharePoint ——2010 新特性之搜索
    BVT测试
    Windows 7的71个运行命令列表
    深入浅出InfoPath——如何在项目中引用GAC中的dll文件
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/6693471.html
Copyright © 2011-2022 走看看