洛谷P2615 神奇的幻方

原题传送门

Description

给定奇数 \(n\),构造一个 \(n\) 阶幻方。

构造规则如下 :
对于一个数 \(k\)\(k\in[2,n^2]\)

  • \((k-1)\) 在第一行但不在最后一列,则将 \(k\) 填在最后一行, \((k-1)\) 所在列的右一列;
  • \((k-1)\) 在最后一列但不在第一行,则将 \(k\) 填在第一列, \((k-1)\) 所在行的上一行;
  • \((k-1)\) 在第一行最后一列,则将 \(k\) 填在 \((k-1)\) 的正下方;
  • \((k-1)\) 既不在第一行,也不在最后一列,如果 \((k-1)\) 的右上方还未填数,则将 \(k\) 填在 \((k-1)\) 的右上方,否则将 \(k\) 填在 \((k-1)\) 的正下方。

Solution

题意很简单,考虑如何记录上一个点的坐标。

这里提供一种较为简单的思路 :

使用两个变量 \(pos_i\)\(pos_j\) 分别记录上一个点在幻方中的位置 \((i,j)\)

其余按照题意模拟即可。

Code

#include<iostream>
#include<cstdio>
using namespace std;
const int Maxn=40;
inline void read(int &x){
	int f=1;
	char ch=getchar();
	x=0;
	while(ch<'0'||ch>'9'){
	    if(ch=='-') f=-1;
	    ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
	    x=(x<<3)+(x<<1)+(ch&15);
	    ch=getchar();
	}
	x*=f;
}
inline void write(int x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
int n;
int map[Maxn][Maxn];
int main(){
	//freopen("ans.txt","w",stdout);
	read(n);
	map[1][n/2+1]=1;
	int posi=1,posj=n/2+1;
	//write(posi),putchar(' '),write(posj);
	for(int i=2;i<=n*n;i++){
		if(posi==1&&posj!=n){
			map[n][posj+1]=i;
			posi=n;posj++;
		}
		else if(posj==n&&posi!=1){
			map[posi-1][1]=i;
			posi--;posj=1;
		}
		else if(posi==1&&posj==n){
			map[2][posj]=i;
			posi++;
		}
		else if(posi!=1&&posj!=n){
			if(map[posi-1][posj+1]==0){
				map[posi-1][posj+1]=i;
				posi--;posj++;
			}
			else{
				map[posi+1][posj]=i;
				posi++; 
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			write(map[i][j]);
			putchar(' ');
		}
		putchar('\n');
	}
	return 0;
}

Others

这道题用了大概 15min 一遍 AC

特此纪念。

posted @ 2020-11-25 17:40  _pwl  阅读(223)  评论(0编辑  收藏  举报
1 2 3
4