算法设计与分析—— 2.4 strassen矩阵乘法+2.5 棋盘覆盖问题

文章目录

    • 2.4 strassen矩阵乘法
    • 2.5 棋盘覆盖问题

算法设计与分析—— 2.4 strassen矩阵乘法+2.5 棋盘覆盖问题_第1张图片

2.4 strassen矩阵乘法

给定两个n×n的矩阵A,B,求C=A×B
算法设计与分析—— 2.4 strassen矩阵乘法+2.5 棋盘覆盖问题_第2张图片
参考链接
Hopcroft和Kerr已经证明(1971),计算2个2×2矩阵的乘积,7次乘法是必要的。因此,要想进一步改进矩阵乘法的时间复杂性,就不能再基于计算2×2矩阵的7次乘法这样的方法了。或许应当研究3×3或5×5矩阵的更好算法。

在Strassen之后又有许多算法改进了矩阵乘法的计算时间复杂性。目前最好的计算时间上界是 O(n2.376)
应用:

科学计算、图像处理、数据挖掘等;回归、聚类、主成分分析、决策树等挖掘算法常涉及大规模矩阵运算。

2.5 棋盘覆盖问题

问题描述:
在一个 2 k × 2 k 2^{k}×2^{k} 2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。

x0、y0:分别表示每次划分后左上角的方块x坐标、y坐标。
x、y:当前划分后特殊方块的x坐标、y坐标。

通过特殊方格的(x,y)和左上的第一方格(x0,y0),来依次判断特殊方格在哪个区域(左上、右上、左下、右下),然后将不含有特殊方格的区域填上特殊方格,规则如下:

  • 左上没有特殊方格,就在涂红的位置(x0+s-1,y0+s-1)填上
  • 右上没有,在右上(x0+s-1,y0+s)填上
  • 左下没有,在左下(x0+s,y0+s-1)填上
  • 右下没有,在右下(x0+s,y0+s)填上
  • 总 结 一 句 就 是 选 择 靠 近 中 心 的 L 位 置 \color{red}总结一句就是选择靠近中心的L位置 L

算法设计与分析—— 2.4 strassen矩阵乘法+2.5 棋盘覆盖问题_第3张图片
不断地划分直至只剩下一个格子,递归结束不再划分。
代码:

#include 
using namespace std;
int i,j;
int a[10][10];
int mark=0;
void ChessBoard(int x0,int y0,int x,int y,int n)
{

    if(n==1) return;
    mark++;
    int t=mark;//记录每个L骨牌的数字
    int s=n/2;//划分后每个区域的大小

    //特殊方块在左上角
    if(x<x0+s&&y<y0+s)
        //对含特殊方块的方格继续划分,注意n变为一半
        ChessBoard(x0,y0,x,y,s);
    else
    {
        //将左上角的区域填充特殊方块
        a[x0+s-1][y0+s-1] = t;
        ChessBoard(x0,y0,x0+s-1,y0+s-1,s);
    }

    //特殊方块在右上角
    if(x<x0+s&&y>=y0+s)
        ChessBoard(x0,y0+s,x,y,s);
    else
    {
        a[x0+s-1][y0+s] = t;
        ChessBoard(x0,y0+s,x0+s-1,y0+s,s);
    }


    //特殊方块在左下角
    if(x>=x0+s&&y<y0+s)
        ChessBoard(x0+s,y0,x,y,s);
    else
    {
        a[x0+s][y0+s-1] = t;
        ChessBoard(x0+s,y0,x0+s,y0+s-1,s);
    }

    //特殊方块在右下角
    if(x>=x0+s&&y>=y0+s)
        ChessBoard(x0+s,y0+s,x,y,s);
    else
    {
        a[x0+s][y0+s] = t;
        ChessBoard(x0+s,y0+s,x0+s,y0+s,s);
    }

}
int main()
{

    int n,x,y;
    cin>>n>>x>>y;
    ChessBoard(0,0,x-1,y-1,n);
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
            printf("%2d ",a[i][j]);

        cout<<endl;
    }

    return 0;
}

输出:(递归的顺序对结果输出数字有影响)
算法设计与分析—— 2.4 strassen矩阵乘法+2.5 棋盘覆盖问题_第4张图片

你可能感兴趣的:(C语言,算法导论)