HDU 2276 Kiki & Little Kiki 2 矩阵构造和乘法

Kiki & Little Kiki 2

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2032    Accepted Submission(s): 1046

 

Problem Description

There are n lights in a circle numbered from 1 to n. The left of light 1 is light n, and the left of light k (1< k<= n) is the light k-1.At time of 0, some of them turn on, and others turn off. 
Change the state of light i (if it's on, turn off it; if it is not on, turn on it) at t+1 second (t >= 0), if the left of light i is on !!! Given the initiation state, please find all lights’ state after M second. (2<= n <= 100, 1<= M<= 10^8)
 

Input

The input contains one or more data sets. The first line of each data set is an integer m indicate the time, the second line will be a string T, only contains '0' and '1' , and its length n will not exceed 100. It means all lights in the circle from 1 to n.
If the ith character of T is '1', it means the light i is on, otherwise the light is off.
 

Output

For each data set, output all lights' state at m seconds in one line. It only contains character '0' and '1.

Sample Input

 

1 0101111 10 100000001

Sample Output

 

1111000 001000010

解题报告:这题想了好久,但没有思路,就看了看解题报告。。。


此题最重要的一个点就是:

               a1=(an+a1)%2 ; a2=(a1+a2)%2   ...    an=(an-1+an)%2;


知道了这个

那么就可以根据这个构建矩阵了

                                                                      开始时

                                           a1 a2 a3 a4 a5 a6 a7 a8 a9................................an

                                                                      一次改变后

                                     a1 = (a1+an)%2,a2 = (a1+a2)%2,a3 = (a2+a3)%2,……an = (an+an-1)%2

                                                                 经过时间T之后

这个可根据矩阵的几次方得来(这里以n=4为例)

                                  A1               1          0           0             1  ^T     a1

                                  A2              1          1            0             0           a2

                                  A3       =     0          1            1             0    *      a3

                                  A4              0          0            1             1            a4

(Ai表示经过T之后新的ai)

 实现代码如下:

(忘记初始化了,搞了我哦好久)

/* ************
当看不懂代码时
动手敲敲会好得多
************ */
#include<iostream>
#include<cmath>
#include <cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long

char a[105];//用于存 灯 的状态
int len;
struct mat
{
    ll m[105][105];
    mat()
    {
        memset(m,0,sizeof(m));
    }
};
mat mul(mat &A,mat &B)
{
    mat C;
    for(int i=0;i<len;i++)
    {
         for(int j=0;j<len;j++)
         {
                for(int k=0;k<len;k++)
                {
                    C.m[i][j]=(C.m[i][j]+A.m[i][k]*B.m[k][j])%2;
                }
         }

     }
    return C;
}
mat pow(mat A,int n)
{
    mat B;
    for(int i=0;i<len;i++) B.m[i][i]=1;
    while(n)
    {
        if(n&1) B=mul(B,A);
        A=mul(A,A);
        n >>=1;
    }
    return B;
}

int main()
{
    ///a1=(an+a1)%2;a2=(a1+a2)%2 ...an=(an-1+an)%2;

    int t;
    while(scanf("%d",&t)!=EOF)
    {
        getchar();
        scanf("%s",a);
        mat A;
        len=strlen(a);
        for(int i=0;i<len;i++)//处理矩阵
        {
            if(i==0) A.m[i][0]=A.m[i][len-1]=1;
            else A.m[i][i]=A.m[i][i-1]=1;
        }
        mat B=pow(A,t);
        int ans;
        for(int i=0;i<len;i++)
        {
            ans=0;
            for(int j=0;j<len;j++)
            {
                ans=(ans+B.m[i][j]*(a[j]-'0'))%2;
            }
            printf("%d",ans);
        }
        printf("\n");

    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42373330/article/details/81460907