hdu 2276

题意:给一个字符串,字符串的变化规律是看每个字符左边字母的状态(第一个则看最后一个应为是一个环),如果左边的字母为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;
}
原文地址:https://www.cnblogs.com/z1141000271/p/7523172.html