纯数学方法找规律
6. 矩阵中填数. 当给出 N*N 的矩阵,要求用程序填入下列形式的数:
① 倒填,例如N=5 ② 蛇形填数 ③ 回转填数
┌—┬─—┬─┬─—┬─—┐ ┌─┬─—┬—┬—─┬—┐ ┌─—┬─┬—─┬—┬─—┐
│25 │24 │23 │22 │21 │ │ 1 │ 3 │ 4 │10 │11 │ │ 1 │16 │15 │14 │13 │
├─┼─—┼─┼—─┼─—┤ ├─┼——┼─┼—─┼—┤ ├——┼—┼─—┼─┼——┤
│20 │19 │18 │17 │16 │ │ 2 │ 5 │ 9 │12 │19 │ │ 2 │17 │24 │23 │12 │
├—┼—─┼─┼─—┼─—┤ ├─┼——┼─┼——┼─┤ ├─—┼─┼─—┼─┼——┤
│15 │14 │13 │12 │11 │ │ 6 │ 8 │13 │18 │20 │ │ 3 │18 │25 │22 │11 │
├—┼—─┼——┼─┼─—┤ ├—┼─—┼—┼─—┼—┤ ├─—┼—┼——┼─┼——┤
│10 │ 9 │ 8 │ 7 │ 6 │ │ 7 │14 │17 │21 │24 │ │ 4 │19 │20 │21 │10 │
├─┼─—┼─—┼—┼—─┤ ├—┼─—┼—┼─—┼—┤ ├─—┼─┼─—┼—┼——┤
│ 5 │ 4 │ 3 │ 2 │ 1 │ │15 │16 │22 │23 │25 │ │ 5 │ 6 │ 7 │ 8 │ 9 │
└—─┴─┴─—┴─┴─—┘ └─┴─—┴─┴─—┴—┘ └─—┴─┴─—┴—┴─—┘
蛇形分析:
1.对称,a[0][0]+a[4][4]=26, a[i][j]+a[4-i][4-j]=26
2.数字金字塔如下:
1
2 3
4 5 6 第i行行尾数:tail = i*(i+1)/2
7 8 9 10 顺序排列还是逆序排列,得看i的奇偶性
#include <iostream>
#include <iomanip>
#include <cassert>
using namespace std;
void setvalue1(int (*a)[11], int n);
void setvalue2(int (*a)[11], int n);
void setvalue3(int (*a)[11], int circle, int value, int n);
void show(int (*a)[11], int n);
int main()
{
int n;
cout << "Input the class n (1~10): ";
cin >> n;
assert((n >= 1) && (n <= 10));
cout << endl;
int a[11][11];
setvalue1(a,n);
cout << setw(2) << n << "阶倒填矩阵:" << endl;
show(a,n);
setvalue2(a,n);
cout << setw(2) << n << "阶蛇形矩阵:" << endl;
show(a,n);
setvalue3(a,0,1,n);
cout << setw(2) << n << "阶回转矩阵:" << endl;
show(a,n);
}
void setvalue1(int (*a)[11], int n) //倒填
{
int max = n * n;
for (int i=0; i<=n-1; i++)
for (int j=0; j<=n-1; j++)
a[i][j] = max - n*i - j;
}
void setvalue2(int (*a)[11], int n) //蛇形填数
{
for (int i=0; i<=n-1; i++)
for (int j=0; j<=n-1-i; j++)
{
int s = i + j;
int tail = (s+1)*(s+2)/2; //数字金字塔行尾数计算, 金字塔的行 s 为数组行、列标和
a[i][j] = (s%2 == 0) ? (tail-j) : (tail-i); //蛇形排列与行数 s 有关
a[n-1-i][n-1-j] = n*n+1-a[i][j]; //关于 n*n+1 对称
}
}
void setvalue3(int (*a)[11], int circle, int value, int n) //回转填数
{
if (circle < n/2) //转第 circle+1 个圈, circle 从0开始
{
int i,j;
for (i=circle; i<n-1-circle; i++)
a[i][circle] = value++;
for (j=circle; j<n-1-circle; j++)
a[i][j] = value++;
for (i=n-1-circle; i>circle; i--)
a[i][j] = value++;
for (j=n-1-circle; j>circle; j--)
a[i][j] = value++;
setvalue3(a,circle+1,value,n); //递归填内圈
}
else if (n%2 != 0) //奇数阶数组中心的数
a[circle][circle] = value;
}
void show(int (*a)[11], int n)
{
for (int i=0; i<=n-1; i++)
{
for (int j=0; j<=n-1; j++)
cout << setw(4) << a[i][j];
cout << endl;
}
cout << endl;
}