洛谷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
。
特此纪念。
本文欢迎转载,转载时请注明本文链接