题目描述 Description
小明玩一个数字游戏,取个n行n列数字矩阵(其中n为不超过100的奇数),数字的填补方法为:在矩阵中心从1开始以逆时针方向绕行,逐圈扩大,直到n行n列填满数字,请输出该n行n列正方形矩阵以及其的对角线数字之和.
输入描述 Input Description
n(即n行n列)
输出描述 Output Description
n+1行,n行为组成的矩阵,最后一行为对角线数字之和
样例输入 Sample Input
3
样例输出 Sample Output
5 4 3
6 1 2
7 8 9
25
首先可以看出该图是有规律的,可以看做一圈一圈向外扩散,因此你可以看做从1向外面扩散
5 4 3
6 1 2
7 8 9
因此你可以发现每次从该层到下一层可以看做下列步骤:
1.先向右移动一个格
2.向上移动到该层的上一排
3.向左移动到该层的左一列
4.向下移动到该层的下一排
5.向右移动到该层的右一列
代码表示如下:
#include<iostream>
using namespace std;
int p[105][105];
void draw(int n)
{
int flag = 1;
int x = n / 2; int y = n / 2;
p[x][y] = 1;
for (int i = x + 1; i < n; i++)//当前为最内圈,一共到第n-1圈(如n=3时,一共2圈,x+1=2,n=3,正好执行一次)
{
//right
p[x][++y] = ++flag;
//up
while (x > n - i - 1)//(x+1)即i代表所在行数
p[--x][y] = ++flag;
//left
while (y > n - i - 1)
p[x][--y] = ++flag;
//down
while (x < i)
p[++x][y] = ++flag;
//right
while (y < i)
p[x][++y] = ++flag;
}
}
void display(int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j<n; j++)
{
cout << p[i][j] << " ";
}
cout << endl;
}
}
int sum(int n)
{
int sum = 0;
for (int i = 0; i < n; i++)
{
sum += p[i][i] + p[i][n - i - 1];
}
return sum - 1;//减去中间多加的一项 1
}
int main()
{
int n;
cin >> n;
draw(n);
display(n);
cout << sum(n) << endl;
return 0;
}