题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=2276
本题我觉挺好的,思路很好!
题意:给你一排灯泡,如果该灯泡的左边是亮着的,那么该灯泡就要改变状态,否则状态保持不变!其中a1的左边是an.
该题的思想好就好在转为矩阵来模拟操作,m分钟,就相当于m个操作,就相当于作用于矩阵A上m次,即:A^m;
A是类似于:
这种形式,a * A^m 就为最终状态,其中a为每个给定灯泡状态的序列!用数据一模拟一下,的确很妙!
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 110;
struct Matrix
{
int iMatrix[MAXN][MAXN];
};
Matrix iPer, iCell;
void Inite(int n)
{
int i, j;
memset(iPer.iMatrix, 0, sizeof(iPer.iMatrix));
memset(iCell.iMatrix, 0, sizeof(iCell.iMatrix));
for(i = 0; i < n; ++i)
iPer.iMatrix[i][i] = 1;
for(i = 0; i < n; ++i)
for(j = 0; j < n; ++j)
if(i == j)
iCell.iMatrix[i][j] = iCell.iMatrix[i][j+1] = 1;
iCell.iMatrix[n-1][0] = 1;
}
Matrix Multi_Matrix(Matrix a, Matrix b, int n)
{
Matrix c;
int i, j, k;
for(i = 0; i < n; ++i)
{
for(j = 0; j < n; ++j)
{
c.iMatrix[i][j] = 0;
for(k = 0; k < n; ++k)
{
c.iMatrix[i][j] ^= (a.iMatrix[i][k] & b.iMatrix[k][j]);
}
}
}
return c;
}
Matrix Quick_Mod_Matrix(int k, int n)
{
if(k == 1)
return iCell;
Matrix c, tmp;
c = iPer, tmp = iCell;
while(k)
{
if(k&1)
{
c = Multi_Matrix(c, tmp, n);
k--;
}
k >>= 1;
tmp = Multi_Matrix(tmp, tmp, n);
}
return c;
}
int main()
{
int iOperNum, Len, i;
char str[MAXN];
Matrix res, c, tmp;
while(~scanf("%d", &iOperNum))
{
scanf("%s", str);
Len = strlen(str);
Inite(Len);
memset(tmp.iMatrix, 0, sizeof(tmp.iMatrix));
for(i = 0; i < Len; ++i)
tmp.iMatrix[0][i] = str[i] - '0';
c = Quick_Mod_Matrix(iOperNum, Len);
res = Multi_Matrix(tmp, c, Len);
for(i = 0; i < Len; ++i)
printf("%d", res.iMatrix[0][i]);
printf("\n");
}
return 0;
}