zoukankan      html  css  js  c++  java
  • poj3735Training little cats

    链接

    构造矩阵 快速幂求解

    构造矩阵a[i]为每个cati所拥有的花生总数 这里多加一维用来求和,具体是怎么求得可以看下面的一组例子 假设有3个cat a[] = {1,0,0,0}

    构造单位矩阵来保存操作后的解 为什么要是单位矩阵?因为单位矩阵乘以任何矩阵还是原矩阵 这样在单位矩阵上改变要操作的那列(这里用列来表示i只猫的花生数)就能保留下来不被改变的猫的

    花生数

    对于g 1

    (1,0,0,0)*{1,1,0,0

          0,1,0,0

          0,0,1,0

          0,0,0,1}

    这样得出结果(1,1,0,0} 也就是说对于g1 就让mat[0][i]+1就可以了 因为加了k 最后都会变成a[i][i]+a[0][0]*k a[i][i]为前一步的i所拥有的花生数 而a[0][0]始终为1

    类似的 对于e 1

    就是把第1列清0

    s i,j

    就把第i,j列互换

    这样得出一个k个操作后的矩阵T 求解T^m。

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stdlib.h>
     6 #include<vector>
     7 #include<cmath>
     8 #include<queue>
     9 #include<set>
    10 using namespace std;
    11 #define N 102
    12 #define LL long long
    13 #define INF 0xfffffff
    14 const double eps = 1e-8;
    15 const double pi = acos(-1.0);
    16 const double inf = ~0u>>2;
    17 struct Mat
    18 {
    19     LL mat[N][N];
    20 };
    21 int n;
    22 Mat operator * (Mat a,Mat b)
    23 {
    24     Mat c;
    25     memset(c.mat,0,sizeof(c.mat));
    26     int i,j,k;
    27     for(k =0 ; k < n ; k++)
    28     {
    29         for(i = 0 ; i < n ;i++)
    30         {
    31             if(a.mat[i][k]==0) continue;//优化
    32             for(j = 0 ;j < n ;j++)
    33             {
    34                 if(b.mat[k][j]==0) continue;//优化
    35                 c.mat[i][j] += a.mat[i][k]*b.mat[k][j];
    36             }
    37         }
    38     }
    39     return c;
    40 }
    41 Mat operator ^(Mat a,int k)
    42 {
    43     Mat c;
    44     int i,j;
    45     for(i =0 ; i < n ;i++)
    46         for(j = 0; j < n ;j++)
    47         c.mat[i][j] = (i==j);
    48     for(; k ;k >>= 1)
    49     {
    50         if(k&1) c = c*a;
    51         a = a*a;
    52     }
    53     return c;
    54 }
    55 Mat init()
    56 {
    57     int i;
    58     Mat c;
    59     memset(c.mat,0,sizeof(c.mat));
    60     for(i = 0 ; i <= n; i++)
    61     c.mat[i][i] = 1;
    62     return c;
    63 }
    64 int main()
    65 {
    66     int i,j,k,m;
    67     char s[2];
    68     while(cin>>n>>m>>k)
    69     {
    70         if(!n&&!k&&!m) break;
    71         Mat t = init();
    72         for(i = 1; i <=k; i++)
    73         {
    74             int x,y;
    75             cin>>s>>x;
    76             if(s[0]=='g')
    77             t.mat[0][x]++;
    78             else if(s[0]=='e')
    79             {
    80                 for(j = 0; j <= n ;j++)
    81                 t.mat[j][x] = 0;
    82             }
    83             else
    84             {
    85                 cin>>y;
    86                 for(j =0 ; j <= n; j++)
    87                 swap(t.mat[j][x],t.mat[j][y]);
    88             }
    89         }
    90         n++;
    91         t = t^m;
    92         for(i =1 ;i < n-1; i++)
    93         cout<<t.mat[0][i]<<" ";
    94         cout<<t.mat[0][n-1]<<endl;
    95     }
    96     return 0;
    97 }
    View Code

          

  • 相关阅读:
    android学习第一天
    定力
    C++ 虚基类表指针字节对齐
    c++内存对齐 转载
    #Pragma Pack(n)与内存分配
    c++ data语意学
    point类型·
    对象内存 (扩展 Data Structure Alignment)
    reinterpret_cast and const_cast
    static_cast AND dynamic_cast
  • 原文地址:https://www.cnblogs.com/shangyu/p/3621036.html
Copyright © 2011-2022 走看看