一看到开关灯问题,觉得应该是和矩阵有关系的,于是开始向矩阵上靠,发现第i个灯的下一次变化为 (i-1 + i)&1; 这样就可以构造矩阵了,很高兴没有trick
code:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
const int MAXN = 101;
int n,m;
char str[MAXN];
bool dat[MAXN];
bool ans[MAXN];
struct Matrix
{
bool mat[MAXN][MAXN];
}E,A;
void init()
{
int i,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
E.mat[i][j] = (i==j);
A.mat[i][j] = 0;
}
}
A.mat[1][1]=1;
A.mat[1][n]=1;
for(i=2;i<=n;i++)
{
A.mat[i][i-1]=1;
A.mat[i][i]=1;
}
}
Matrix operator * (const Matrix a,const Matrix b)
{
Matrix res;
int i,j,k;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
res.mat[i][j]=0;
for(k=1;k<=n;k++)
{
res.mat[i][j]= (res.mat[i][j] + a.mat[i][k] * b.mat[k][j]) &1;
}
}
}
return res;
}
Matrix operator ^ (const Matrix a,int exp)
{
Matrix res=E;
Matrix tmp=a;
while(exp)
{
if(exp&1)
res = res * tmp;
exp>>=1;
tmp = tmp * tmp;
}
return res;
}
void solve()
{
Matrix tmp = A ^ m;
int i,j;
for(i=1;i<=n;i++)
{
ans[i]=0;
for(j=1;j<=n;j++)
{
ans[i]=(ans[i] + dat[j] * tmp.mat[i][j])&1;
}
}
for(i=1;i<=n;i++)
{
printf("%d",ans[i]);
}
puts("");
}
int main()
{
int i;
while(~scanf("%d",&m))
{
scanf("%s",str);
n=strlen(str);
init();
for(i=0;i<n;i++)
{
dat[i+1] = str[i]-'0';
}
solve();
}
return 0;
}