zoukankan      html  css  js  c++  java
  • HDU 2276

    http://acm.hdu.edu.cn/showproblem.php?pid=2276

    矩阵乘法可以解决的一类灯泡开关问题

    /*
    转移关系为 
    now left now*
    1    0    1 
    1    1    0
    0    1    1
    0    0    0
    
    可知F[i] = (f[i] + f[(n+i-2)%n+1]) % 2 
     
    得到n*n的关系矩阵是
    1 1 0 0 ... 0
    0 1 1 0 ... 0
    0 0 1 1 ... 0
    . . . . ... 0
    . . . . ... 0
    . . . . ... 0
    0 0 0 0 ... 1
    1 0 0 0 ... 1
    */
    #include <iostream> 
    #include <cstdio>
    #include <cstring>
    #include <map>
    
    using namespace std;
    
    #define MOD 2
    
    #define Mat 105 //矩阵大小
      
    struct mat{//矩阵结构体,a表示内容,r行c列 矩阵从1开始  
        int a[Mat][Mat];
        int r, c;  
        mat() {  
            r = c = 0;  
            memset(a, 0, sizeof(a));  
        }  
    };  
    
    void print(mat m) {  
        //printf("%d
    ", m.size);  
        for(int i = 0; i < m.r; i++) {  
            for(int j = 0; j < m.c; j++) printf("%d ", m.a[i][j]);  
            putchar('
    ');  
        }  
    }  
      
    mat mul(mat m1, mat m2, int mod) {  
        mat ans  = mat();
        ans.r = m1.r, ans.c = m2.c;  
        for(int i = 1; i <= m1.r; i++)  
            for(int j = 1; j <= m2.r; j++)  
                if(m1.a[i][j])
                    for(int k = 1; k <= m2.c; k++)  
                        ans.a[i][k] = (ans.a[i][k] + m1.a[i][j] * m2.a[j][k]) % mod;  
        return ans;  
    } 
    
    mat quickmul(mat m, int n, int mod) {  
        mat ans = mat();  
        for(int i = 1; i <= m.r; i++) ans.a[i][i] = 1;  
        ans.r = m.r, ans.c = m.c;  
        while(n) {  
            if(n & 1) ans = mul(m, ans, mod);  
            m = mul(m, m, mod);  
            n >>= 1;  
        }  
        return ans;  
    }  
    
    /* 
    初始化ans矩阵 
    mat ans = mat(); 
    ans.r = R, ans.c = C;  
    ans = quickmul(ans, n, mod); 
    */
    
    char a[105];
    
    int main() { 
        int m; 
        while(~scanf("%d", &m)) {
            scanf("%s", a);
            int n = strlen(a);
            mat A = mat();
            A.r = 1, A.c = n;
            for(int i = 1; i <= n; i++)
                A.a[1][i] = a[i-1] - '0';    
            mat G = mat();
            G.r = G.c = n;
            for(int i = 1; i < n; i++) {
                G.a[i][i] = G.a[i][i+1] = 1;
            }
            G.a[n][1] = G.a[n][n] = 1;
            mat ans = quickmul(G, m, MOD);
            ans = mul(A, ans, MOD);
            for(int i = 1; i <= n; i++)
                printf("%d", ans.a[1][i]);
            putchar('
    ');
        }
        return 0;
    }
    View Code
  • 相关阅读:
    LeetCode 382. Linked List Random Node
    LeetCode 398. Random Pick Index
    LeetCode 1002. Find Common Characters
    LeetCode 498. Diagonal Traverse
    LeetCode 825. Friends Of Appropriate Ages
    LeetCode 824. Goat Latin
    LeetCode 896. Monotonic Array
    LeetCode 987. Vertical Order Traversal of a Binary Tree
    LeetCode 689. Maximum Sum of 3 Non-Overlapping Subarrays
    LeetCode 636. Exclusive Time of Functions
  • 原文地址:https://www.cnblogs.com/xiaohongmao/p/4578875.html
Copyright © 2011-2022 走看看