hdu_4920_Matrix multiplication

題目大意

計算 n * n 的矩陣 A 和 B 模3下的積。

思路

強算的複雜度爲n^3,想辦法用bitset優化。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bitset>
#define INF 0x3f3f3f3f
#define rep0(i, n) for (int i = 0; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define rep_0(i, n) for (int i = n - 1; i >= 0; i--)
#define rep_1(i, n) for (int i = n; i > 0; i--)
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define mem(x, y) memset(x, y, sizeof(x))
#define MAXN 810

using namespace std;
bitset<MAXN> bs[MAXN], bs1[MAXN];
int A[MAXN][MAXN], B[MAXN][MAXN], n;
int C[MAXN][MAXN];
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
    #endif // ONLINE_JUDGE

    while (scanf("%d", &n) != EOF)
    {

        for (int i = 0; i < n; i++)
        {
            bs[i].reset();
            bs1[i].reset();

        }
        mem(C, 0);

        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                scanf("%d", &A[i][j]);
                A[i][j] %= 3;
                if (A[i][j])
                    bs[i][j] = 1;

            }
        }

        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                scanf("%d", &B[i][j]);
                B[i][j] %= 3;
            }
        }


        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                if (B[i][j])
                    bs1[j][i] = 1;
            }
        }

        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                C[i][j] += (bs[i] & bs1[j]).count();
            }
        }

        for (int i = 0; i < n; i++)
        {
            //bs[i].reset();
            bs1[i].reset();
        }

        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                if (B[i][j] == 2)
                    bs1[j][i] = 1;
            }
        }

        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                C[i][j] += (bs[i] & bs1[j]).count();
            }
        }

        for (int i = 0; i < n; i++)
        {
            bs[i].reset();
            //bs1[i].reset();
        }


        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (A[i][j] == 2)
                    bs[i][j] = 1;

            }
        }

        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                if (B[i][j])
                    bs1[j][i] = 1;
            }
        }


        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                C[i][j] += (bs[i] & bs1[j]).count();
                C[i][j] %= 3;
            }
        }

        for (int i = 0; i < n; i++)
        {
            //bs[i].reset();
            bs1[i].reset();
        }

        for (int j = 0; j < n; j++)
        {
            for (int i = 0; i < n; i++)
            {
                if (B[i][j] == 2)
                    bs1[j][i] = 1;
            }
        }




        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                C[i][j] += (bs[i] & bs1[j]).count();
                C[i][j] %= 3;
            }
        }



        for (int i = 0; i < n; i++)
        {
            printf("%d", C[i][0]);
            for (int j = 1; j < n; j++)
                printf(" %d", C[i][j]);
            printf("\n");
        }


    }

    return 0;
}

把 A 的每一行存爲一個bitset,同理存B的每一列,但每個元素最大爲2:

a1 = x1 + y1  a2 = x2 + y2

a1 = 2時,a1 = 1 + 1
a1 = 1時,a1 = 1 + 0   ...

a1 * a2 = (x1 + y1) * (x2 + y2) = x1 * x1 + x1 * y2 + y1 * x2 + y1 * y2

分解爲 4 次bitset & 運算 


也可以將矩陣分爲兩個bitset數組,一個記錄1,一個記錄2。



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