题目大意:题目大意给定一系列灯的初始状态,0代表暗,1代表亮,每一秒所有的灯都有可能发生状态切换,
切换规则:当前灯的左边第一个灯是亮的,则当前的灯切换状态,如果当前灯的左边第一盏灯是暗的,则当前灯的状态无需变化!
注意:最左边的参考左右边那栈灯。
题目分析;
首先有两种情况:
左边第一盏灯亮的:
当前灯的动作: 1->0; 0->1;
左边第一盏灯暗的:
当前灯的动作:
1->1; 0->0;
我们可以看到的是, 可以用一个方程来模拟这个过程: F[i] = ( f [ i] +f [i+n-2]%n+1 )%2;
所以我们只要计算这个值就OK啦。
然后由于数据过大,开数组肯定会爆掉~
这里我们要想到的是 矩阵是一个模拟递归的高效算法
这里我们要构造一个 可以计算如上的方程的矩阵:
1 0 0...0 1
1 1 0...0 0
0 1 1..0 0
0 0 1..0 0
. . . 0 ....
. . .0.....
0 0 0..0 1
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 105;
const int mod = 2;
struct Mat
{
int num[N][N];
Mat()
{
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++)
num[i][j] = 0;
}
};
Mat mul(Mat a, Mat b, int n)
{
Mat r;
for(int i = 0; i < n; i++)
for(int k = 0; k < n; k++)
{
if(a.num[i][k] == 0)
continue;
for(int j = 0; j < n; j++)
{
if(b.num[k][j] == 0)
continue;
r.num[i][j] = (r.num[i][j] + a.num[i][k] * b.num[k][j]) % mod;
}
}
return r;
}
Mat mal(Mat init, Mat unit, int m, int n)
{
while(m)
{
if(m & 1)
{
unit = mul(init, unit, n);
m--;
}
else
{
init = mul(init, init, n);
m >>= 1;
}
}
return unit;
}
int main()
{
int m;
while(cin >> m)
{
char str[N];
cin >> str;
Mat init, unit;
int len = strlen(str);
for(int i = 0; i < len; i++)
{
unit.num[i][0] = str[i] - '0';
}
init.num[0][0] = 1; init.num[0][len - 1] = 1;
int k = 0;
for(i = 1; i < len; i++)
{
for(int j = k; j < k + 2; j++)
init.num[i][j] = 1;
k++;
if(k == len - 1)
break;
}
Mat ans;
ans = mal(init, unit, m, len);
for(i = 0 ; i < len; i++)
cout << ans.num[i][0];
cout << endl;
}
}
死也想不明白下面这个代码为什么就TLE了。。
/*#include <iostream>
#include <algorithm>
#include <string>
char str[102];
using namespace std;
struct mat
{
int map[101][101];
};
mat unit,res,temp;
int t,n;
mat mul(mat a,mat b)
{
mat c;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
// if(a.map[i][j]==0)continue;
c.map[i][j]=0;
for(int k=1;k<=n;k++)
{
// if(b.map[j][k]==0)continue;
c.map[i][j]=(c.map[i][j]+(a.map[i][k]*b.map[k][j])%2)%2;
}
}
return c;
}
void TOW()
{
mat ans=unit;
mat bns=temp;
while(t)
{
if(t%2==1)
{
t--;
ans=mul(ans,bns);
}
else
{
bns=mul(bns,bns);
t=t/2;
}
}
res=mul(res,ans);
}
int main()
{
int len;
memset(unit.map,0,sizeof(unit.map));
for(int i=1;i<=100;i++)
unit.map[i][i]=1;
while(scanf("%d",&t)!=EOF)
{
memset(res.map,0,sizeof(res.map));
memset(temp.map,0,sizeof(temp.map));
scanf("%s",&str);
len=strlen(str);
n=len;
for(i=1;i<=len;i++)
res.map[1][i]=str[len-i]-'0';
for(i=1;i<=n;i++)
{
if(i!=n)
temp.map[i][i]=temp.map[i+1][i]=1;
else
temp.map[1][n]=temp.map[n][n]=1;
}
TOW();
for(i=n;i>=1;i--)
printf("%d",res.map[1][i]);
printf("\n");
}
return 0;
}*/