hdu 2276 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): 2915 Accepted Submission(s): 1546
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)
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.
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
有n盏灯,每秒后如果左边的等是开了,那么当前的灯就变成反状态,否则不变。
左边 原来 现在
1 0 1
1 1 0
0 1 1
0 0 0
现在=原来^左边 由于用加法公式才符合用矩阵快速幂
所以可以变成 现在 = (左边+原来)% 2
所以得到公式:
an 1 1 . . . 0 0 an
an-1 0 1 1 . . . 0 an-1
. . .
. = . .
. . .
a2 0 0 . . . 1 1 a2
a1 1 0 . . . 0 1 a1
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int mod = 200907; 5 const int N = 110; 6 char str[N]; 7 int len, a[N]; 8 struct mat{ 9 ll m[N][N]; 10 mat(){ 11 memset(m, 0, sizeof(m)); 12 } 13 }; 14 15 mat mul(mat &A, mat &B) { 16 mat C; 17 for(int i = 0; i < len; i ++) { 18 for(int j = 0; j < len; j ++) { 19 for(int k = 0; k < len; k ++) { 20 C.m[i][j] = (C.m[i][j] + A.m[i][k]*B.m[k][j]) % 2; 21 } 22 } 23 } 24 return C; 25 } 26 27 mat pow(mat A, int n) { 28 mat B; 29 for(int i = 0; i < len; i ++) B.m[i][i] = 1; 30 while(n) { 31 if(n&1) B = mul(B, A); 32 A = mul(A, A); 33 n >>= 1; 34 } 35 return B; 36 } 37 int main() { 38 int m; 39 while(scanf("%d%s",&m,str) != EOF){ 40 memset(a, 0, sizeof(a)); 41 len = strlen(str); 42 mat A; 43 for(int i = 0; i < len; i ++) { 44 A.m[i][i] = A.m[i][(i+1)%len] = 1; 45 } 46 A = pow(A, m); 47 for(int i = 0; i < len; i ++) { 48 for(int j = 0; j < len; j ++) { 49 a[i] += A.m[len-i-1][j]*(str[(len-j-1)%len]-'0'); 50 } 51 } 52 for(int i = 0; i < len; i ++) printf("%d",a[i]%2); 53 printf("\n"); 54 } 55 return 0; 56 }