CCF 201512-5 矩陣 50分代碼

問題描述

試題編號: 201512-5
試題名稱: 矩陣
時間限制: 1.0s
內存限制: 256.0MB
問題描述:

問題描述

  創造一個世界只需要定義一個初狀態和狀態轉移規則。
  宏觀世界的物體運動規律始終跟物體當前的狀態有關,也就是說只要知道物體足夠多的狀態信息,例如位置、速度等,我們就能知道物體之後任意時刻的狀態。
  現在小M創造了一個簡化的世界。
  這個世界中,時間是離散的,物理規律是線性的:世界的初始狀態可以用一個m維向量b(0)表示,狀態的轉移方式用m×m的矩陣A表示。
  若已知這個世界當前的狀態是b,那麼下一時刻就等於b左乘狀態轉移矩陣A,即Ab
  這個世界中,物體的狀態也是離散的,也就是說可以用整數表示。再進一步,整數都可以用二進制編碼拆分爲有限位0和1。因此,這裏的矩陣A和向量b的每個元素都是0或1,矩陣乘法中的加法運算視爲異或運算(xor),乘法運算視爲與運算(and)。
  具體地,設矩陣Ai行第j列的元素爲aij,向量b的第i個元素爲bi。那麼乘法Ab所得的第k個元素爲
  (ak,1 and b1) xor (ak,2 and b2) xor ⋯ xor (ak,m and bm)
  矩陣和矩陣的乘法也有類似的表達。
  小M發現,這樣的矩陣運算也有乘法結合律,例如有A(Ab)=(AA)b=A2b
  爲了保證自己創造的世界維度不輕易下降,小M保證了矩陣A可逆,也就是說存在一個矩陣A-1,使得對任意向量d,都有A-1Ad=d
  小M想了解自己創造的世界是否合理,他希望知道這個世界在不同時刻的狀態。
  具體地,小M有n組詢問,每組詢問會給出一個非負整數k,小M希望你幫他求出Akb

輸入格式

  輸入第一行包含一個整數m,表示矩陣和向量的規模。
  接下來m行,每行包含一個長度爲m的01串,表示矩陣A
  接下來一行,包含一個長度爲m的01串,表示初始向量b(0)。(b(0)是列向量,這裏表示它的轉置)
  注意:01串兩個相鄰的數字之間均沒有空格。
  接下來一行,包含一個正整數n,表示詢問的個數。
  最後n行,每行包含一個非負整數k,表示詢問Akb(0)。
  注意:k可能爲0,此時是求A0b(0) =b(0)。

輸出格式

  輸出n行,每行包含一個01串,表示對應詢問中Akb(0)的結果。
  注意:01串兩個相鄰的數字之間不要輸出空格。

樣例輸入

3
110
011
111
101
10
0
2
3
14
1
1325
6
124124
151
12312

樣例輸出

101
010
111
101
110
010
100
101
001
100

評測用例規模與約定

  本題使用10個評測用例來測試你的程序。
  對於評測用例1,m = 10,n = 100,k ≤ 103。
  對於評測用例2,m = 10,n = 100,k ≤ 104。
  對於評測用例3,m = 30,n = 100,k ≤ 105。
  對於評測用例4,m = 180,n = 100,k ≤ 105。
  對於評測用例5,m = 10,n = 100,k ≤ 109。
  對於評測用例6,m = 30,n = 100,k ≤ 109。
  對於評測用例7,m = 180,n = 100,k ≤ 109。
  對於評測用例8,m = 600,n = 100,k ≤ 109。
  對於評測用例9,m = 800,n = 100,k ≤ 109。
  對於評測用例10,m = 1000,n = 100,k ≤ 109。

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;

const int maxn=200;
int n;
struct Matrix
{
    int m[maxn][maxn];
};
Matrix P;
Matrix I;
Matrix Matrixmul(Matrix a,Matrix b)
{
    int i,j,k;
    Matrix c;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
        {
                c.m[i][j]=0;
                for(int k=0; k<n; k++)
                {
                    c.m[i][j]^=(a.m[i][k]&b.m[k][j]);
                }
        }
    }
    return c;
}
Matrix quickpow(int n)
{
    Matrix m=P,b=I;
    while(n)
    {
        if(n&1)
        {
            b=Matrixmul(b,m);
        }
        n=n>>1;
        m=Matrixmul(m,m);
    }
    return b;
}
int main()
{

    for(int i=0; i<maxn; i++)
        for(int j=0; j<maxn; j++)
            if(i==j)
                I.m[i][j]=1;
            else
                I.m[i][j]=0;
   scanf("%d",&n);
    getchar();
    char ss[maxn];
    int b[maxn];
    for(int i=0; i<n; i++)
    {
        gets(ss);
        for(int j=0; j<n; j++)
            P.m[i][j]=ss[j]-'0';
    }
    gets(ss);
    for(int j=0; j<n; j++)
        b[j]=ss[j]-'0';
    int  t;
    scanf("%d",&t);
    int ans[maxn];
    while(t--)
    {
        int c;
        scanf("%d",&c);

            Matrix x=quickpow(c);
            for(int i=0; i<n; i++)
            {
                ans[i]=0;
                for(int j=0; j<n; j++)
                    ans[i]^=(x.m[i][j]&b[j]);
            }

        for(int i=0; i<n; i++)
            printf("%d",ans[i]);
        puts("");
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章