Kiki & Little Kiki 2
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2032 Accepted Submission(s): 1046
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
解题报告:这题想了好久,但没有思路,就看了看解题报告。。。
此题最重要的一个点就是:
a1=(an+a1)%2 ; a2=(a1+a2)%2 ... an=(an-1+an)%2;
知道了这个
那么就可以根据这个构建矩阵了
开始时
a1 a2 a3 a4 a5 a6 a7 a8 a9................................an
一次改变后
a1 = (a1+an)%2,a2 = (a1+a2)%2,a3 = (a2+a3)%2,……an = (an+an-1)%2
经过时间T之后
这个可根据矩阵的几次方得来(这里以n=4为例)
A1 1 0 0 1 ^T a1
A2 1 1 0 0 a2
A3 = 0 1 1 0 * a3
A4 0 0 1 1 a4
(Ai表示经过T之后新的ai)
实现代码如下:
(忘记初始化了,搞了我哦好久)
/* ************
当看不懂代码时
动手敲敲会好得多
************ */
#include<iostream>
#include<cmath>
#include <cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
char a[105];//用于存 灯 的状态
int len;
struct mat
{
ll m[105][105];
mat()
{
memset(m,0,sizeof(m));
}
};
mat mul(mat &A,mat &B)
{
mat C;
for(int i=0;i<len;i++)
{
for(int j=0;j<len;j++)
{
for(int k=0;k<len;k++)
{
C.m[i][j]=(C.m[i][j]+A.m[i][k]*B.m[k][j])%2;
}
}
}
return C;
}
mat pow(mat A,int n)
{
mat B;
for(int i=0;i<len;i++) B.m[i][i]=1;
while(n)
{
if(n&1) B=mul(B,A);
A=mul(A,A);
n >>=1;
}
return B;
}
int main()
{
///a1=(an+a1)%2;a2=(a1+a2)%2 ...an=(an-1+an)%2;
int t;
while(scanf("%d",&t)!=EOF)
{
getchar();
scanf("%s",a);
mat A;
len=strlen(a);
for(int i=0;i<len;i++)//处理矩阵
{
if(i==0) A.m[i][0]=A.m[i][len-1]=1;
else A.m[i][i]=A.m[i][i-1]=1;
}
mat B=pow(A,t);
int ans;
for(int i=0;i<len;i++)
{
ans=0;
for(int j=0;j<len;j++)
{
ans=(ans+B.m[i][j]*(a[j]-'0'))%2;
}
printf("%d",ans);
}
printf("\n");
}
return 0;
}