洛谷日志(2)

把vscode里写的臭鱼烂虾翻出来写博客,我真是太闲(bushi)。

主要是临近期末了,写点东西缓解一下焦虑。

摘自洛谷题库P5461

题目链接

以后就不放原题的文字了,因为洛谷的题目复制粘贴出来有些数学符号有问题(可恶)

分析一下题目,首先我们有一个元素全为1的n阶矩阵。实际上就是需要写程序去模拟这样一个过程:将一个矩阵平均分为四个分块矩阵,然后将左上角的分块矩阵全部变为0,在将剩下的三个分块矩阵重复这个过程。

由此,解决这个问题的方法就是写一个函数,通过递归处理这个矩阵。

#include 

int main()
{
    void laplace(int x, int *p_matrix, int len);
    
    int n, len = 1;
    scanf("%d",&n);
    //获取矩阵阶数
    for(int i = 0;i < n;i++) len *= 2;
    int matrix[len][len];
    //矩阵初始化为1
    for (int i = 0;i < len;i++){
        for (int j = 0;j < len;j++){
            matrix[i][j] = 1;
        }
}

获得n阶矩阵。

void laplace(int x, int *p_matrix, int len){
    //递归边界,为两阶矩阵的时候进行返回
    if (x == 2) {
        *p_matrix = 0;
        return;
    }
    //对分块四元矩阵的左上分块进行遍历赋值为0
    for (int i = 0;i < x/2;i++){
        for (int j = 0;j < x/2;j++){
            *(p_matrix + j + len*i) = 0;
        }
    }
    //对剩下的三个分块进行递归
    laplace(x/2, p_matrix + x/2, len);
    laplace(x/2, p_matrix + len*x/2 + x/2, len);
    laplace(x/2, p_matrix + len*x/2, len);
    
}

创建一个拉普拉斯函数(叫这个名字是因为联想到了线性代数的拉普拉斯定理,也是分为四个分块矩阵,但是实际上两者没有任何关系啦)。

函数各部分的作用如注释所写。将矩阵进行分块的操作实际上是由指针操作的,移动指针后指针所指向的元素也就是”新分块矩阵的首元“,那么向右下展开的就是分块矩阵(只不过需要注意的是指针移到分块矩阵的下一行所需加的数还得是最大矩阵的列数,因为你并不能将一个二维数组确确实实的切开,而只是用指针虚拟的调取其中的一部分)。

函数入参的分别是当前处理矩阵的阶数,操作指针和最大矩阵的阶数。

递归过程在递到阶数为2的时候进行归。

你可能感兴趣的:(洛谷日志,算法,c语言)