19、数圈
【问题描述】
以1为中心,用2,3,4, …, n, …, n*n的数字围绕着中心输出数圈, 如若n=4,则
7 8 9 10
6 1 2 11
5 4 3 12
16 15 14 13
【输入形式】
一个整数n(1<=n<=10)
【输出形式】
数圈矩阵
【样例输入】
5
【样例输出】
21 22 23 24 25
20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13
数圈问题属于模拟问题,说明这个题目不太需要大量的数学思考(我以为),所以我就直接开始一个二维矩阵的模拟数据填充,(其实,我本来想用递归函数来进行填充的,但是后来发现,如果我要写一个函数的基本上就把所有东西都传进去了,就放弃了)。
填充顺序,我选择倒着来,即从nn开始填起,一直填到1为止,问题就变成了找每次填充的边界表达式:
(一下,偶数填充,奇数填充,指的是sum的初始值是偶数平方还是奇数平方)
这个题目就可以分解,每次填充半圈,因为实际上n+1数圈就是在n数圈的基础上在左上或是右下填充了范围为nn+1~(n+1)*(n+1)的数字。
//19、数圈
#include <iostream>
using namespace std;
int main(){
int n=0;
cin >> n;
int circle[n][n];
for(int i=0;i<n;i++)//初始化二维矩阵
for(int j=0;j<n;j++)
circle[i][j] = 0;
int type = n%2;/*标识符:标识先进行偶数填充还是奇数填充,
这关系到我们后边对于边界的确定,因为如果n是偶数,先进行偶
数填充,那么奇数填充就从倒数第二列开始,否则就从倒数第一
列开始*/
for(int i=0;i<n;i++){//i是为了标识次数,同时也是圈数
int sum = (n-i)*(n-i);//每次填充的最大数据
if((n-i)%2!=0){//奇数填充
for(int k = n-(i+1)/2-1;k>=i/2;k--)
circle[i/2][k] = sum--;
for(int j = i/2+1;j<n-i/2-1+type;j++)//type的用处
circle[j][i/2] = sum--;
}
else{//偶数填充
for(int k = i/2+type;k < n-i/2;k++)//type的用处,就是标识每次的边界
circle[n-i/2-1][k] = sum--;
for(int j = n-i/2-2;j>=i/2+type;j--)
circle[j][n-i/2-1] = sum--;
}
}
for(int i=0;i<n;i++){//输出
for(int j=0;j<n;j++){
cout << circle[i][j] <<" ";
}
cout << endl;
}
return 0;
}