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 1000000007 using namespace std; int Map[MAX][MAX]; void MagicSquare(int n) { Map[1][(n+1)/2]=1;//首先填第一行中间列 1 int 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; }