1 奇数阶幻方构造法
(1) 将1放在第一行中间一列;
(2) 从2开始直到n×n止各数依次按下列规则存放:按 45°方向行走,向右上,即每一个数存放的行比前一个数的行数减1,列数加1
(3) 如果行列范围超出矩阵范围,则回绕。例如1在第1行,则2应放在最下一行,列数同样加1;
(4) 如果按上面规则确定的位置上已有数,或上一个数是第1行第n列时,则把下一个数放在上一个数的下面。
#include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<stdio.h> #include<stdlib.h> #include<queue> #include<math.h> #include<map> #define INF 0xffffffff #define MAX 1005 #define Temp 1000000000 #define MOD 1000000007using namespace std;int Map[MAX][MAX];void MagicSquare(int n) {Map[1][(n+1)/2]=1;//首先填第一行中间列 1int x=1,y=(n+1)/2;for(int i=2;i<=n*n;i++){if(x==1 && y==n)//若当前位置为(1,n)则下一个数填到当前数字下方 {x=x+1;y=y;Map[x][y]=i;continue;}if(y==n)//若超出边界则回绕 {if(Map[x-1][1]==-1){x=x-1;y=1;Map[x][y]=i;}else{x=x+1;Map[x][y]=i;}continue;}if(x==1)//若超出边界则回绕 {if(Map[n][y+1]==-1){x=n;y=y+1;Map[x][y]=i;}else{x=x+1;Map[x][y]=i;}continue;}else//向右上方填 {if(Map[x-1][y+1]!=-1)//若右上方已有数字,当前数字填当前位置下方 {x=x+1;y=y;Map[x][y]=i;}else{x=x-1;y=y+1;Map[x][y]=i;}continue;}} }int main() {int n;while(scanf("%d",&n)!=EOF){memset(Map,-1,sizeof(Map));MagicSquare(n);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){printf("%d%c",Map[i][j],j==n?'\n':' ');}}}return 0; }