P2615 [NOIP2015 提高组] 神奇的幻方
#include<bits/stdc++.h>
using namespace std;
int main()
{
bool visi[40][40];
int a[40][40];//幻方矩阵
fill(a[0],a[0]+40*40,0);
fill(visi[0],visi[0]+40*40,false);
int x,y;//用于记录上一次所填左
int last=1;
int n;//矩阵维度
cin>>n;
x=1;
y=n/2+1;//初始化第一个数的位置
a[x][y]=1;
visi[x][y]=true;
//依次循环各个数字
for(int i=2;i<=n*n;i++)
{
if(x==1&&y!=n&&visi[n][y+1]==false)
{
//若 (K-1) 在第一行但不在最后一列,则将 K 填在最后一行, (K−1) 所在列的右一列;
visi[n][y+1]=true;
a[n][y+1]=i;
x=n;
y=y+1;
last=a[n][y+1];
continue;
}
else if(y==n&&x!=1&&visi[x-1][1]==false)
{
//若 (K-1) 在最后一列但不在第一行,则将 K 填在第一列, (K-1)所在行的上一行
visi[x-1][1]=true;
a[x-1][1]=i;
x=x-1;
y=1;
last=a[x-1][1];
continue;
}
else if(x==1&&y==n&&visi[x+1][y]==false)
{
//若 (K-1) 在第一行最后一列,则将 K 填在 (K-1) 的正下方
visi[x+1][y]=true;
a[x+1][y]=i;
x=x+1;
y=y;
last=a[x+1][y];
continue;
}
else
{
//若 (K-1) 既不在第一行,也不在最后一列,如果 (K-1) 的右上方还未填数,则将 K 填在 (K−1) 的右上方,否则将 K填在 (K-1)的正下方
if(x!=1&&y!=n)
{
if(a[x-1][y+1]==0)
{
if(visi[x-1][y+1]==false)
{
visi[x - 1][y + 1] = true;
a[x - 1][y + 1] = i;
x = x - 1;
y = y + 1;
last = a[x - 1][y + 1];
continue;
}
}
else
{
if(visi[x+1][y]==false)
{
visi[x+1][y]=true;
a[x+1][y]=i;
x=x+1;
y=y;
last=a[x+1][y];
continue;
}
}
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
return 0;
}

