Kiki & Little Kiki 2(矩阵快速幂)

Kiki & Little Kiki 2

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1894    Accepted Submission(s): 979


Problem Description
There are n lights in a circle numbered from 1 to n. The left of light 1 is light n, and the left of light k (1< k<= n) is the light k-1.At time of 0, some of them turn on, and others turn off.
Change the state of light i (if it's on, turn off it; if it is not on, turn on it) at t+1 second (t >= 0), if the left of light i is on !!! Given the initiation state, please find all lights’ state after M second. (2<= n <= 100, 1<= M<= 10^8)

 

 

Input
The input contains one or more data sets. The first line of each data set is an integer m indicate the time, the second line will be a string T, only contains '0' and '1' , and its length n will not exceed 100. It means all lights in the circle from 1 to n.
If the ith character of T is '1', it means the light i is on, otherwise the light is off.

 

 

Output
For each data set, output all lights' state at m seconds in one line. It only contains character '0' and '1.
 

 

Sample Input
1
0101111
10
100000001
 

 

Sample Output

 

1111000
001000010

      题意:

      给出 m (1 ~ 10 ^ 8),代表有 m 秒钟,后给出 n(1 ~ 100) 个灯的开关状态(环)。每一秒钟如果该灯的左边灯是 1 的话,则改变自身灯的状态,输出当过了 m 秒后灯的状态。

 

      思路:

      矩阵快速幂。设 a,b,c 三盏灯:

      ai+1 = (ci + ai)% 2;

      bi+1 = (ai + bi)% 2;

      ci+1 = (bi + ci)% 2;所以可以得到矩阵:

      Kiki & Little Kiki 2(矩阵快速幂)_第1张图片

      vector 中的 size 函数导致了 TLE, 每次循环求长度浪费了不少的时间,在已知的长度下就可以不用求了。

     

       AC:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

typedef vector<int> vec;
typedef vector<vec> mat;
int len;

mat mul (mat a, mat b) {
    mat c(len, vec(len));

    for (int i = 0; i < len; ++i) {
        for (int j = 0; j < len; ++j) {
            for (int k = 0; k < len; ++k) {
                c[i][j] = (a[i][k] * b[k][j] + c[i][j]) % 2;
            }
        }
    }

    return c;
}

mat pow (mat a, int n) {
    mat b(len, vec(len));
    for (int i = 0; i < len; ++i) {
        b[i][i] = 1;
    }

    while (n > 0) {
        if (n & 1) b = mul(b, a);
        a = mul(a, a);
        n >>= 1;
    }

    return b;
}

int main() {
    int n;
    char str[105];

    while (~scanf("%d%s", &n, str)) {

        len = strlen(str);

        mat a(len, vec(len));
        for (int i = 0; i < len; ++i) {
            if (!i) a[i][i] = a[i][len - 1] = 1;
            else a[i][i] = a[i][i - 1] = 1;
        }

        a = pow(a, n);

        for (int i = 0; i < len; ++i) {
            int res = 0;
            for (int j = 0; j < len; ++j) {
                res ^= (a[i][j] & (str[j] - '0'));
            }
            printf("%d", res);
        }

        printf("\n");
    }

    return 0;
}

 

你可能感兴趣的:(it)