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。



猜你喜欢

转载自blog.csdn.net/Anna__1997/article/details/80209525
今日推荐