Kiki & Little Kiki 2Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2302 Accepted Submission(s): 1177
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
Sample Output
|
感谢大排骨给我灵感,1A有大排骨的功劳。O(∩_∩)O~~
题意:给你N个围成一圈的灯,1号灯的左边是N号灯,N号灯的右边是1号灯。
这些灯的开关状态在时刻改变,这里给出第i个灯的变化规律(1表示该灯是开着的,0表示该灯是关着的)
当第i个灯初始状态为1时,若它左边灯状态为1,则下一秒第i个灯状态变为0,反之不改变。
当第i个灯初始状态为0时,若它左边灯状态为1,则下一秒第i个灯状态变为1,反之不改变。
已经给你这N个灯的状态,问你m秒后这N个灯的状态。
分析:m = 10^8,显然不能模拟,只能用矩阵做。找出前后两个状态之间的联系,构造出矩阵就可以了。
对第i个灯,下一秒它的状态改变只取决于它左边灯的状态A和自己的状态B,其它灯不会影响到第i个灯状态的改变。
这样我们只需要求出A和B就可以了,至于其它灯的状态可以全看做0。这个用矩阵很好实现。
比如说,我们想要第i个灯的状态,只需要把第i个灯在矩阵的相应位置赋值为1。把其它灯的状态看做0更简单,把矩阵中其它灯的对应位置赋值为0。
对AB以及相应的B的改变,则有4种可能:(1) 01 -> 1; (2) 10 -> 1;(3) 00 ->0 (4) 11 -> 0。
这里不要想远了,不要想什么异或,我就是想到异或才卡了一会。
好好思考下,会发现这是两数之和对2取余后的结果(一开始想到了,没去模拟结果o(╯□╰)o)。
给个图示矩阵:
结果 初始矩阵 F矩阵
#include <cstdio> #include <cstring> #include <algorithm> #define MAXN 110 #define LL long long using namespace std; struct Matrix { int a[MAXN][MAXN]; int r, c; }; Matrix ori, res; int F[MAXN];//F矩阵 void init(char *s) { int len = strlen(s); ori.r = ori.c = len;//初始矩阵 res.r = res.c = len;//单位矩阵 memset(ori.a, 0, sizeof(ori.a)); memset(res.a, 0, sizeof(res.a)); for(int i = 0; i < len; i++) { int k = s[i] - '0'; F[i] = k; ori.a[i][i] = res.a[i][i] = 1; if(i == 0) ori.a[i][len-1] = 1; else ori.a[i][i-1] = 1; } } Matrix muitl(Matrix x, Matrix y) { Matrix z; memset(z.a, 0, sizeof(z.a)); z.r = x.r, z.c = y.c; for(int i = 0; i < x.r; i++) { for(int k = 0; k < x.c; k++) { if(x.a[i][k] == 0) continue; for(int j = 0; j < y.c; j++) z.a[i][j] = (z.a[i][j] + x.a[i][k] * y.a[k][j]) % 2; } } return z; } void Matrix_mod(int n) { while(n) { if(n & 1) res = muitl(ori, res); ori = muitl(ori, ori); n >>= 1; } } int Ans[MAXN]; void solve(int n) { Matrix_mod(n); memset(Ans, 0, sizeof(Ans)); for(int i = 0; i < res.r; i++) { for(int k = 0; k < res.c; k++) { if(res.a[i][k] == 0) continue; Ans[i] = (Ans[i] + res.a[i][k] + F[k]) % 2; } } for(int i = 0; i < res.r; i++) printf("%d", Ans[i]); printf("\n"); } int main() { int m; char str[110]; while(scanf("%d", &m) != EOF) { scanf("%s", str); init(str);//构造矩阵 solve(m); } return 0; }