幻方是一个方形整数数组,它每行的和,每列的和及两条对角线上的和全部相等,下面的图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> using namespace std; //本程序按照题目的排序方法打印出幻方 //2005年4月24日 3:10 void main(){
int **a,i,j,count=1,n,m,flag=0;//count是计算器,用来计算输入数字的个数,flag是标记,n,m分别是首个数字的插入位置 int b[255],N,sum=0,count1; //数组B是来分别记录行,列,对角线元素的总和 cout<<"please input the N control the array long and width:\n";//输入N为二维数组,N一定要为奇数 cin>>N; 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 count1=N*N; n=0; m=N/2; a[n][m]=1; count++; while(count<=count1){ cout<<"please intput the "<<count<<"th number:\n";//输入2-25,一定要按照递增输入即是(2,3,4,5,6,7。。。。。25) if(n==0&&m!=N-1){//当当前位置是第0行并且不是第4列 n=N-1; if(a[n][m+1]==0) flag=1; //当要插入的位置没有数字时 if(flag==1) { m++; fflush(stdin); cin>>a[n][m]; flag=0; count++; } else{ //当当前位置有已经数字时,在当前位置的前一个数插入 n++; fflush(stdin);//用来消去输入数字按的空格 cin>>a[n][m]; 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--; fflush(stdin); cin>>a[n][m]; flag=0; count++; } else{ n++; m=N-1; fflush(stdin); cin>>a[n][m]; 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) { fflush(stdin); cin>>a[n][m]; flag=0; count++; } else{ n=1; m=N-1; fflush(stdin); cin>>a[n][m]; 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--; fflush(stdin); cin>>a[n][m]; flag=0; count++; } else{ m=N-1; n=0; fflush(stdin); cin>>a[n][m]; count++; } } else{//当是其他位置时 if(a[n-1][m+1]==0) flag=1; if(flag==1){ n--; m++; fflush(stdin); scanf("%d",&a[n][m]); flag=0; count++; } else{ n++; fflush(stdin); cin>>a[n][m]; count++; } } } cout<<"output the array:\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; 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; else cout<<"the array is not dream square!"<<endl; for (int i=0;i<N;i++) delete[] a[i]; //注意撤销次序,先列后行,与设置相反 delete[] a; } 我加了详细的注释,希望不会这道题目的人可以看明白