strassen算法-方阵相乘

实现两个n*n方阵相乘的Strassen算法。假设n=2kEOJ—1050。

#include <iostream>
#include <stdio.h>

using namespace std;
typedef int diarray [100][100];
diarray object[500];
int sp;

void add(int c[][100],int a[][100],int b[][100],int n);
void sub(int c[][100],int a[][100],int b[][100],int n);
void multi(int c[][100],int a[][100],int b[][100],int n);

int main()
{
    int n;
    scanf("%d",&n);
    int i,j,k;
    int a[100][100],b[100][100],c[100][100];
    for(i=0; i<n; i++)
    {
        int size;
        scanf("%d",&size);//输入矩阵大小

        for(j=0; j<size; j++)//输入第一个矩阵
            for(k=0; k<size; k++)
                scanf("%d",&a[j][k]);

        for(j=0; j<size; j++)//输入第二个矩阵
            for(k=0; k<size; k++)
                scanf("%d",&b[j][k]);

        multi(a,b,c,size);//做乘法

        for(j=0; j<size; j++)//输出
            for(k=0; k<size; k++)
            {
                printf("%d",c[j][k]);
                if(k!=size-1)  putchar(' ');
                else putchar('\n');
            }
    }
    return 0;
}


void multi(int a[][100],int b[][100],int c[][100],int n)
{
    //申请所需空间
    diarray &a11=object[sp++],&a12=object[sp++],&a21=object[sp++],&a22=object[sp++],
            &b11=object[sp++],&b12=object[sp++],&b21=object[sp++],&b22=object[sp++],
            &c11=object[sp++],&c12=object[sp++],&c21=object[sp++],&c22=object[sp++],
            &m1=object[sp++],&m2=object[sp++],&m3=object[sp++],&m4=object[sp++],&m5=object[sp++],&m6=object[sp++],&m7=object[sp++],
            &t=object[sp++],&t0=object[sp++];

    if(n==1)
    {
        c[0][0]=a[0][0]*b[0][0];
        sp-=21;
        return;
    }
    n>>=1;
    int i,j;

    //分别将a、b分别分成四个数组
    for(i=0; i<n; ++i)
    {
        for(j=0; j<n; ++j)
        {
            a11[i][j]=a[i][j];
            a12[i][j]=a[i][j+n];
            a21[i][j]=a[i+n][j];
            a22[i][j]=a[i+n][j+n];
        }
    }

    for(i=0; i<n; ++i)
    {
        for(j=0; j<n; ++j)
        {
            b11[i][j]=b[i][j];
            b12[i][j]=b[i][j+n];
            b21[i][j]=b[i+n][j];
            b22[i][j]=b[i+n][j+n];
        }
    }

    sub(b12,b22,t,n);
    multi(a11,t,m1,n);

    add(a11,a12,t,n);
    multi(t,b22,m2,n);

    add(a21,a22,t,n);
    multi(t,b11,m3,n);

    sub(b21,b11,t,n);
    multi(a22,t,m4,n);

    add(a11,a22,t,n);
    add(b11,b22,t0,n);
    multi(t,t0,m5,n);

    sub(a12,a22,t,n);
    add(b21,b22,t0,n);
    multi(t,t0,m6,n);

    sub(a11,a21,t,n);
    add(b11,b12,t0,n);
    multi(t,t0,m7,n);

    add(m4,m5,t,n);
    sub(m2,m6,t0,n);
    sub(t,t0,c11,n);

    add(m1,m2,c12,n);

    add(m3,m4,c21,n);

    add(m5,m1,t,n);
    add(m3,m7,t0,n);
    sub(t,t0,c22,n);

    //整理放回c中
    for (i=0; i<n; ++i)
    {
        for (j=0; j<n; ++j)
        {
            c[i][j]=c11[i][j];
            c[i][j+n]=c12[i][j];
            c[i+n][j]=c21[i][j];
            c[i+n][j+n]=c22[i][j];
        }
    }

    sp-=21;//释放空间
}
void add(int a[][100],int b[][100],int c[][100],int n)
{
    int i,j;
    for(i=0; i<n; ++i)
    {
        for(j=0; j<n; ++j)
        {
            c[i][j]=a[i][j]+b[i][j];
        }
    }
}

void sub(int a[][100],int b[][100],int c[][100],int n)
{
    int i,j;
    for (i=0; i<n; ++i)
    {
        for(j=0; j<n; ++j)
        {
            c[i][j]=a[i][j]-b[i][j];
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值