zoukankan      html  css  js  c++  java
  • hdu2276 矩阵构造

    题意:
         给了n个灯泡的状态,他们绕成一个环,0是灭,1是亮,每一秒灯泡的状态都会改变,规则是如果当前这个灯泡的左边的灯泡当前是状态1,那么下一秒当前的这个灯泡状态就改变0变1,1变0,最后问你m秒后的状态。

    思路:
         我们先找当前状态和下一个状态的关系(状态也就是秒),我们可以抽象成这么一种关系,如果第i个灯泡的状态是ai,那么下一秒的第i个灯泡的状态是上一秒的(ai + ai-1)%2,这样关系就出来了,我们构造矩阵,现在就以n=5为例:


    上一秒                                  下一秒
    a1 a2 a3 a4 a5     1 1 0 0 0    a1 a2 a3 a4 a5
                       0 1 1 0 0
                   *   0 0 1 1 0
                       0 0 0 1 1
                       1 0 0 0 1  


    ok然后就矩阵快速幂了,还有提示下,矩阵是不满足交换律的,也就是说如果把5*5的矩阵放在前面,然后* 初始矩阵=下一个状态,这样构造出来的矩阵会和上面不同,但两个都是对的,最后乘出来的答案一样(只要别吧各自的顺序弄错了)。


    #include<stdio.h>
    #include<string.h>
    
    typedef struct
    {
       int mat[105][105];
    }A;
    
    A mat_mat(A a ,A b ,int n)
    {
       A c;
       memset(c.mat ,0 ,sizeof(c.mat));
       for(int k = 1 ;k <= n ;k ++)
       for(int i = 1 ;i <= n ;i ++)
       if(a.mat[i][k])
       for(int j = 1 ;j <= n ;j ++)
       c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % 2;
       return c;
    }
    
    A Quick_mat(A a ,int b ,int n)
    {
       A c;
       memset(c.mat ,0 ,sizeof(c.mat));
       for(int i = 1 ;i <= n ;i ++)
       c.mat[i][i] = 1;
       while(b)
       {
          if(b&1) c = mat_mat(c ,a ,n);
          a = mat_mat(a ,a ,n);
          b >>= 1;
       }
       return c;
    }
    
    int main ()
    {
       int n ,i ,j ,m;
       int num[105];
       char str[105];
       A aa;
       while(~scanf("%d" ,&m))
       {
          scanf("%s" ,str);
          n = strlen(str);
          for(i = 1 ;i <= n ;i ++)
          num[i] = str[i-1] - '0';
          memset(aa.mat ,0 ,sizeof(aa.mat));
          aa.mat[1][1] = aa.mat[n][1] = 1;
          for(i = 2 ;i <= n ;i ++)
          aa.mat[i-1][i] = aa.mat[i][i] = 1;
          aa = Quick_mat(aa ,m ,n);
          for(i = 1 ;i <= n ;i ++)
          {
             int now = 0;
             for(j = 1 ;j <= n ;j ++)
             now = (now + num[j] * aa.mat[j][i]) % 2;
             printf("%d" ,now);
          }
          puts("");
       }
       return 0;
    }
          
    

  • 相关阅读:
    How To Build CyanogenMod Android for smartphone
    CentOS安装Code::Blocks
    How to Dual boot Multiple ROMs on Your Android SmartPhone (Upto Five Roms)?
    Audacious——Linux音乐播放器
    How to Dual Boot Multiple ROMs on Your Android Phone
    Everything You Need to Know About Rooting Your Android Phone
    How to Flash a ROM to Your Android Phone
    什么是NANDroid,如何加载NANDroid备份?
    Have you considered compiled a batman-adv.ko for android?
    BATMAN—Better Approach To Mobile Adhoc Networking (B.A.T.M.A.N.)
  • 原文地址:https://www.cnblogs.com/csnd/p/12062814.html
Copyright © 2011-2022 走看看