2390: 【普及-】【P2615】神奇的幻方

内存限制:128 MB 时间限制:1.000 S
评测方式:文本比较 命题人:
提交:2 解决:2

题目描述

幻方是一种很神奇的 lns="http://www.w3.org/1998/Math/MathML">× 矩阵:它由数字 lns="http://www.w3.org/1998/Math/MathML">1,2,3,,× 构成,且每行、每列及两条对角线上的数字之和都相同。

当 lns="http://www.w3.org/1998/Math/MathML"> 为奇数时,我们可以通过下方法构建一个幻方:

首先将 lns="http://www.w3.org/1998/Math/MathML">1 写在第一行的中间。

之后,按如下方式从小到大依次填写每个数 lns="http://www.w3.org/1998/Math/MathML">(=2,3,,×) :

  1. 若 lns="http://www.w3.org/1998/Math/MathML">(1) 在第一行但不在最后一列,则将 lns="http://www.w3.org/1998/Math/MathML"> 填在最后一行, lns="http://www.w3.org/1998/Math/MathML">(1) 所在列的右一列;
  2. 若 lns="http://www.w3.org/1998/Math/MathML">(1) 在最后一列但不在第一行,则将 lns="http://www.w3.org/1998/Math/MathML"> 填在第一列, lns="http://www.w3.org/1998/Math/MathML">(1) 所在行的上一行;
  3. 若 lns="http://www.w3.org/1998/Math/MathML">(1) 在第一行最后一列,则将 lns="http://www.w3.org/1998/Math/MathML"> 填在 lns="http://www.w3.org/1998/Math/MathML">(1) 的正下方;
  4. 若 lns="http://www.w3.org/1998/Math/MathML">(1) 既不在第一行,也不在最后一列,如果 lns="http://www.w3.org/1998/Math/MathML">(1) 的右上方还未填数,则将 lns="http://www.w3.org/1998/Math/MathML"> 填在 lns="http://www.w3.org/1998/Math/MathML">(1) 的右上方,否则将 lns="http://www.w3.org/1998/Math/MathML"> 填在 lns="http://www.w3.org/1998/Math/MathML">(1) 的正下方。

现给定 lns="http://www.w3.org/1998/Math/MathML"> ,请按上述方法构造 lns="http://www.w3.org/1998/Math/MathML">× 的幻方。

输入

一个正整数 lns="http://www.w3.org/1998/Math/MathML">,即幻方的大小。

输出

共 lns="http://www.w3.org/1998/Math/MathML"> 行,每行 lns="http://www.w3.org/1998/Math/MathML"> 个整数,即按上述方法构造出的 lns="http://www.w3.org/1998/Math/MathML">× 的幻方,相邻两个整数之间用单空格隔开。

样例输入 复制

3

样例输出 复制

8 1 6
3 5 7
4 9 2

提示

对于lns="http://www.w3.org/1998/Math/MathML">100%的数据,对于全部数据, lns="http://www.w3.org/1998/Math/MathML">139 且 lns="http://www.w3.org/1998/Math/MathML"> 为奇数。

NOIp2015 提高组 d1t1

#include<bits/stdc++.h>
using namespace std;
int n,g[40][40],x,y;
int main(){
    cin>>n;
    g[1][n/2+1]=1;
    x=1;y=n/2+1;
    for (int i=2;i<=n*n;i++) {
    	if (x==1&&y!=n)  //第一行但不是最后一列
		    g[n][y+1]=i,x=n,y++;
		else if (y==n&&x!=1) //最后一列但不是第一行
		    g[x-1][1]=i,x--,y=1;
		else if (x==1&&y==n) //第一行最后一列
		    g[2][n]=i,x=2;
		else if (x!=1&&y!=n) {  //不在第一行,也不在最后一列
		    if (g[x-1][y+1]==0)  //右上方未填数
			    g[x-1][y+1]=i,x--,y++; 
			else
			    g[x+1][y]=i,x++;
			continue;
		} 
	}
	for (int i=1;i<=n;i++) {
		for (int j=1;j<=n;j++)
		    cout<<g[i][j]<<" ";
		cout<<endl;
	}
	return 0;
}