zoukankan      html  css  js  c++  java
  • POJ 3735 Training little cats【矩阵的快速求幂】


    POJ 3735 Training little cats


    算法核心:矩阵建模,矩阵的快速幂


    大意:已知有n只猫咪,开始时每只猫咪有花生米0颗,先有一组操作:
    由下面三个中的k个操作组成:
    g i 给i只猫咪一颗花生米
    e i 让第i只猫咪吃掉它拥有的所有花生米
    s i j 将猫咪i与猫咪j的拥有的花生米交换

      现将上述操作做m次后,问每只猫咪有多少颗花生米?

    分析:
    因m的数据范围较大,用矩阵连乘。
    构建矩阵模型,peanut[N] = {0,0,。。。。0,1}:即前n个数为0,最后一个数取1
    matrix[N][N],初始化条件下为单位矩阵,。。。
    对猫咪进行操作转化为在对矩阵peanut进行操作,一组操作过程转化为矩阵matrix,那么m次操作,即对peanut*(matrix^m)
    EXP:
    input:
    316

    g
    1
    g
    2
    g
    2
    s
    12
    g
    3
    e
    2

    初始化下矩阵:peanut 
    0001 即每只猫咪的花生米个数为0

    初始化下matrix为单位矩阵
    1000

    0100
    0010
    0001

    经过操作
    g
    1
    给1号1颗花生米,即在第一列的最后一行加1
    1000
    0100
    0010
    1001

    g
    2
    1000
    0100
    0010
    1101

    g
    2
    1000
    0100
    0010
    1201

    s
    12
    //即交换第1,2列
    0100
    1000
    0010
    2101

    g
    3
    0100
    1000
    0010
    2111

    e
    2
    //将第2列全部置为0
    0000
    1000
    0010
    2011

    最后peanut
    = peanut*matrix*matrix.....*matrix = peanut*(matrix^m)故可用矩阵快速求幂
    peanut的前n个数即为每只猫咪拥有的花生米数


    代码




    #include
    <stdio.h>
    #include
    <string.h>
    constint N =100+5;
    struct Matrix
    {
    __int64 matrix[N][N];
    __int64 row,coloumn;
    Matrix(){
    memset(matrix,
    0,sizeof(matrix));
    }
    };

    Matrix getE(__int64 n)
    //获取n*n的单位矩阵
    {
    Matrix matrix;
    matrix.coloumn
    =n;
    matrix.row
    = n;
    int i;
    for(i=0;i<n;i++)
    {
    matrix.matrix[i][i]
    =1;
    }
    return matrix;
    }

    Matrix initP(__int64 n)
    //初始化花生米矩阵
    {
    Matrix matrix;
    matrix.coloumn
    = n;
    matrix.row
    =1;
    matrix.matrix[
    0][n-1]=1;
    return matrix;
    }

    Matrix mutiply(Matrix a,Matrix b)
    //返回a*b
    {
    __int64 i,j,k;
    Matrix ans;
    ans.row
    = a.row;
    ans.coloumn
    = b.coloumn;
    for(i=0;i<a.row;i++)
    for(k=0;k<a.coloumn;k++)
    if(a.matrix[i][k])//优化
    for(j=0;j<b.coloumn;j++)
    {

    ans.matrix[i][j]
    =ans.matrix[i][j]+a.matrix[i][k]*b.matrix[k][j];
    }

    return ans;
    }

    int main()
    {
    __int64 n,m,k;
    while(scanf("%I64d%I64d%I64d",&n,&m,&k)!=EOF)
    {
    Matrix matrix;
    //操作矩阵
    Matrix peanut;//花生米
    if(n==0&&m==0&&k==0)break;
    matrix
    = getE(n+1);
    peanut
    = initP(n+1);

    __int64 i;
    char op[5];
    __int64 x,y;
    while(k--)
    {

    scanf(
    "%s",op);
    if(op[0]=='g')
    {
    scanf(
    "%I64d",&x);//给x一颗花生米
    matrix.matrix[n][x-1]++;
    }
    else
    if(op[0]=='e')
    {
    scanf(
    "%I64d",&x);//x吃掉所有的花生米
    for(i=0;i<=n;i++)
    matrix.matrix[i][x
    -1]=0;
    }
    else
    {
    scanf(
    "%I64d%I64d",&x,&y);//交换x与y的花生米
    for(i=0;i<=n;i++)
    {
    __int64 tt
    = matrix.matrix[i][x-1];
    matrix.matrix[i][x
    -1]=matrix.matrix[i][y-1];
    matrix.matrix[i][y
    -1] = tt;
    }
    }

    }



    while(m)
    {
    if(m&1)
    {
    peanut
    = mutiply(peanut,matrix);
    }
    m
    >>=1;
    matrix
    = mutiply(matrix,matrix);
    }

    printf(
    "%I64d",peanut.matrix[0][0]);
    for(i=1;i<n;i++)
    printf(
    " %I64d",peanut.matrix[0][i]);
    printf(
    "\n");

    }

    return0;
    }
  • 相关阅读:
    安全测试WEB安全渗透测试基础知识(三)
    二次开发的Selenium Demo版本
    服务端性能测试工具校验v1.2
    渗透H5棋牌游戏棋牌游戏开发
    安全测试WEB安全渗透测试基础知识(一)
    源码网址
    使用ScribeFire写网易博客 imsho@126的日志 网易博客
    ScribeFire:和firefox完美结合的博客离线编辑器 博客联盟
    如何设置让 Everything 在 Win7 下开机启动 小众软件
    流言终结者——C语言内存管理 michael的个人空间 开源中国社区
  • 原文地址:https://www.cnblogs.com/AndreMouche/p/1946432.html
Copyright © 2011-2022 走看看