幻方是一个方形整数数组,它每行的和,每列的和及两条对角线上的和全部相等,下面的图1.5给出幻方
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
(1)编写程序读一个正方形整数数组,并判断它是否一个幻方。
(2)编写程序用下面的方法生成一个幻方,此方法仅当正方形大小是奇数时可用。开始时将1放在顶行的中间
位置,将后续整数2,3,....分别写入前个数字所在位置的上行偏右一格。当到达顶行时(比如1就在顶
行),返回到底行继续前进,就好像底行是直接在顶行上面一样。当到达最右列的时,继续到最左列,就好
像最左列直接在最右列的右边。当到达的位置已被占据时,就直接在前一个数的下面位置处插入新数。按照
这种方法构造的5×5幻方如图1.5中所示。
#include<iostream> //本程序是实现C++数据结构与程序设计序第一章p37页
using namespace std; //p1.(2)小题,按照题目的方法打印出幻方
void play(int **,int); //用来组成幻方
void output(int **,int); //用来输出跟判断幻方
void main(){
int **a,N,i,j;
cout<<"please input the N confirm the long and the width which the array's:\n";//输入N为二维数组,N一定要为奇数
while(1)
{
cin>>N;
if(N%2==0)
{cout<<"you inputed a wrong number,please input again:"<<endl;
continue;
}
else break;
}
a=new int*[N]; //动态分配数组
for(i=0;i<N;i++)
a[i]=new int[N];
for(i=0;i<N;i++)
for(j=0;j<N;j++)
a[i][j]=0;//数组空时全置0
play(a,N);
output(a,N);
for (int i=0;i<N;i++) delete[] a[i]; //注意撤销次序,先列后行,与设置相反
delete[] a;
} void play(int **a,int N)
{ int count=1,n,m,flag=0,count1;//count是计算器,用来计算输入数字的个数,n,m分别是首个数字的插入位置,flag是标记
count1=N*N;
n=0;
m=N/2;
a[n][m]=1;
count++;
while(count<=count1){
if(n==0&&m!=N-1){//当当前位置是第0行并且不是第4列
n=N-1;
if(a[n][m+1]==0)
flag=1; //当要插入的位置没有数字时
if(flag==1)
{ m++;
a[n][m]=count;
flag=0;
count++;
}
else{ //当当前位置有已经数字时,在当前位置的前一个数的下方插入
n++;
a[n][m]=count;
count++;
}
}
else if(m==N-1&&n!=0&&n!=N-1){//当当前位置是第4列并且不是第0行跟第4行时
m=0;
if(a[n-1][m]==0)
flag=1;
if(flag==1)
{n--;
a[n][m]=count;
flag=0;
count++;
}
else{
n++;
m=N-1;
a[n][m]=count;
count++;
}
}
else if(m==N-1&&n==0)//当当前位置是第4列并且是第0行
{ m=0;
n=N-1;
if(a[n][m]==0)
flag=1;
if(flag==1)
{
a[n][m]=count;
flag=0;
count++;
}
else{
n=1;
m=N-1;
a[n][m]=count;
count++;
}
}
else if(m==N-1&&n==N-1)//当当前位置时第4列并且是第4行时
{ m=0;
if(a[n-1][m]==0)
flag=1;
if(flag==1)
{
n--;
a[n][m]=count;
flag=0;
count++;
}
else{
m=N-1;
n=0;
a[n][m]=count;
count++;
}
}
else{//当是其他位置时
if(a[n-1][m+1]==0)
flag=1;
if(flag==1){
n--;
m++;
a[n][m]=count;
flag=0;
count++;
}
else{
n++;
a[n][m]=count;
count++;
}
}
} }
void output(int **a,int N)
{ int b[255],count,flag,i,j,sum=0; //数组b是来分别记录行,列,对角线元素的总和,flag是标记
cout<<"output the anrry:\n";
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{ if(j%N==0)
cout<<endl;
cout<<a[i][j]<<'\t';
} cout<<endl<<endl;
count=0;
for(i=0;i<N;i++)//计算行的总和
for(j=0;j<N;j++)
{ sum+=a[i][j];
b[count++]=sum;
sum=0;
} for(j=0;i<N;i++)//计算列的总和
for(i=0;j<N;j++)
{sum+=a[i][j];
b[count++]=sum;
sum=0;
} for(i=0;i<N;i++)//计算对角线总和
for(j=0;j<i;j++)
sum+=a[i][j];
b[count++]=sum;
sum=0;
for(i=0;i<N;i++)//计算对角线总和
for(j=N-1;j>N-i;j--)
sum+=a[i][j];
b[count++]=sum;
flag=0;
for(i=0;i<count;i++)
if(b[0]==b[i])//判断行,列,对角线是否相等,相等就是幻方,不相等就不是!
flag=1;
if(flag==1)
cout<<"the array is dream square!"<<endl<<endl;
else cout<<"the array is not dream square!"<<endl;
}
[此贴子已经被作者于2006-6-20 23:23:33编辑过]