题意:给一个字符串,字符串的变化规律是看每个字符左边字母的状态(第一个则看最后一个应为是一个环),如果左边的字母为1就反转。
题解:考虑状态转移方程,然后关于为1就反转其实就是一个同或的过程,可以通过模2加法来实现。状态转移方程
(这里不具体讲了,只有0,1的状态,自己枚举一下state1和state2,矩阵相乘后都是能正确转移的)
其他灯的考虑都是一样的,最终:
ac代码:
#include <cstdio> #include <cstring> #include <iostream> #include <queue> #include <stack> #define mt(a) memset(a,0,sizeof(a)) using namespace std; const int mod=10000; struct Martix { int mp[105][105]; int r,c; }; Martix mul(Martix a,Martix b) { int r=a.r; int c=b.c; Martix temp; temp.r=r; temp.c=c; for(int i=0;i<r;i++) { for(int j=0;j<c;j++) { temp.mp[i][j]=0; for(int k=0;k<r;k++) { temp.mp[i][j]=(a.mp[i][k]*b.mp[k][j]+temp.mp[i][j])%2; } } } return temp; } string s; Martix pow(Martix a,int k) { Martix ans; int len=s.length(); memset(ans.mp,0,sizeof(ans.mp)); ans.r=len; ans.c=1; for(int i=0;i<len;i++) ans.mp[i][0]=s[i]-'0'; while(k) { if(k&1) ans=mul(a,ans); k/=2; a=mul(a,a); } return ans; } int main() { int n; while(~scanf("%d",&n)) { cin>>s; Martix a; int len=s.length(); memset(a.mp,0,sizeof(a.mp)); a.mp[0][0]=a.mp[0][len-1]=1; a.r=a.c=len; for(int i=1;i<len;i++) a.mp[i][i]=a.mp[i][i-1]=1; Martix key=pow(a,n); for(int i=0;i<len;i++) cout<<key.mp[i][0]; cout<<endl; } return 0; }