1.需求规格说明
(<五号宋体>,具体内容:问题描述,求解的问题是什么)
给一个奇数 N(1<N<2000),把从 1 到 N的整数排成一个 N 行 N 列的方阵,使该方阵的每一行、列和对角线上的 N 个数的和都相等
2.总体分析与设计
从 1 开始,依次插入各自然数,直到 N*N 为止。选择插入位置原则为:
1)第一个位置在第一行的正中;
2)新位置应当处于最近一个插入位置右上方,但如右上方位置已超出方阵上边界,则新位
置取应选列的最下一个位置;如超出右边界则新边界取应选行的最左一个位置;
3)若最近一个插入元素为 N 的整数倍,则选下面一行同列的位置为新位置
3.编码
(<五号宋体>,具体内容:问题是如何解决的,编码过程中的困难与解决方法。)
在设计的时候动态二维数组的时候网上给出了两种解决方案一种是双重指针,另一种使用vector。但是都是残缺不全的,比如双重指针作者在写的时候没有或者残缺delete的部分,因为数据最后一个会很大所以如果有泄露的情况会很严重,所以我选择了vector这种很实用的方法。相关的实现为
头文件
#include<vector>
#include<iomanip>
声明:
//注意下面这一行:vector <int后两个 "> "之间要有空格!否则会被认为是重载 "> > "。
vector<vector<int> > M(n,vector<int>(n));
在下面就可以用M[i][j]这种形式来进行调用。
普通的双指针声明和delete
int **p;
p=(int ** )new int *[n];
for(int i=0;i<n;i++){
p[i]=new int[n];
}
p[n-2][n-2]=9;
cout<<p[n-2][n-2]<<endl;
//动态分配的删除
for(int i=0;i<n;i++){
delete[]p[i];
}
delete[]p;
5.小结
(<五号宋体>,具体内容:经验与体会,或需要改进的地方)
这次主要是在收集如何动态申请二维数组这个点上,我两种方法都已经能正确的申请和删除,这个算法的话因为有算法提示,一步步的跟着来的话最后也自己出来了。
6.附录
(<五号宋体>,部分核心代码)
int i=0,N,j,t=1;
N=n;
j=N/2;
M[i][j]=t++;
while (t<=(N*N))
{
if (M[i][j]%N==0)
{
i++;
j=j;
M[i][j]=t++;
}
else if(i==0){
if (j==N-1)
{
i++;
j=j;
M[i][j]=t++;
}
else{
i=N-1;
j++;
M[i][j]=t++;
}
}
else if(j==N-1){
i--;
j=0;
M[i][j]=t++;
}
else{
i--;
j++;
M[i][j]=t++;
}
}