蛇形矩阵问题

题目描述

小明玩一个数字游戏,取个n行n列数字矩阵(其中n为不超过100的奇数),数字的填补方法为:在矩阵中心从1开始以逆时针方向绕行,逐圈扩大,直到n行n列填满数字,请输出该n行n列正方形矩阵以及其的对角线数字之和.

解答

使用分治算法, 如果给出蛇形矩阵 n * n 的前 m - 1层填充结果, 按照定义很容易填充第 m 层, 从而可以得到整个蛇形矩阵的填充图.

代码:

#include <iostream>
using namespace std;

void arrInsert(int **arr, int n, int m);
int main() {
    int n;
    cin >> n;
    /*动态生成二维数组*/
    int **arr;
    arr = new int *[n];
    for(int i = 0; i < n; ++i) {
        arr[i] = new int[n];
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            arr[i][j] = 0;
        }
    }

    /*填充矩阵*/
    if(n % 2) { //奇数
        arrInsert(arr, n, n / 2); //填充 n * n矩阵的 n / 2层
    }
    /*显示结果*/
    int sum = 0; //保存对角线的和
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cout << arr[i][j] << " ";
            if (i == j ) { //对角线
                sum += arr[i][j];
            }
            else if(j - n / 2 == n / 2 - i) { //反对角线
                sum += arr[i][j];
            }
        }
        cout << endl;  
    }
    cout << sum << endl;

    /*释放内存*/
    for(int i = 0; i < n; ++i) {
        delete[] arr[i];
    }
    delete[] arr;
    return 0;
}

void arrInsert(int **arr, int n, int m) {
    int mid = n / 2;
    if(m == 0) {
        arr[mid][mid] = 1;
    }
    else {
        arrInsert(arr, n, m - 1); //填充里面的 m - 1层
        arr[mid + m - 1][mid + m] = arr[mid + m - 1][mid + m - 1] + 1;
        for (int i = mid + m - 2; i >= mid - m; --i) {
            arr[i][mid + m] = arr[i + 1][mid + m] + 1;
        }
        for (int j = mid + m - 1; j >= mid - m; --j) {
            arr[mid - m][j] = arr[mid - m][j + 1] + 1;
        }
        for (int i = mid - m + 1; i <= mid + m; ++i) {
            arr[i][mid - m] = arr[i - 1][mid - m] + 1;
        }
        for (int j = mid - m + 1; j <= mid + m; ++j) {
            arr[mid + m][j] = arr[mid + m][j - 1] + 1;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值