实现两个n*n方阵相乘的Strassen算法。假设n=2k。EOJ—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];
}
}
}