神奇的幻方(模拟)

幻方是一个很神奇的 N×N 矩阵,它的每行、每列与对角线,加起来的数字和都是相同的。我们可以通过以下方法构建一个幻方。(阶数为奇数)

第一个数字写在第一行的中间

下一个数字,都写在上一个数字的右上方:

如果该数字在第一行,则下一个数字写在最后一行,列数为该数字的右一列
如果该数字在最后一列,则下一个数字写在第一列,行数为该数字的上一行
如果该数字在右上角,或者该数字的右上方已有数字,则下一个数字写在该数字的下方
输入格式
一个数字 N(N ≤ 20)。

输出格式
按上方法构造的 (2N−1)×(2N−1) 的幻方。

输出时每行末尾的多余空格,不影响答案正确性

样例输入

3

样例输出

17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9

解题思路:

#include<iostream>
#include<cstring>
using namespace std;
int n,cnt;
int mp[200][200];
int main(){
	cin >> n;
	int x,y,nx,ny;
	x = 0;
	y = (2 * n - 1) / 2;//列数 2
	mp[x][y] = ++cnt;//1
	while(true){
		if(cnt == (2 * n - 1) * (2 * n - 1))break;
		int ny = (y + 1) % (2 * n - 1); //3 % 5 =3
		if(x == 0){
			nx = 2 * n - 2; // 4
		}else{
			nx = x - 1;	
		}
		if( x == 0 && y == 2 * n - 2){
			nx = 1;
			ny = 2 * n - 2;//4
			mp[nx][ny] = ++cnt;
		}else if(mp[nx][ny]){
			nx = (x + 1) % (2 * n - 1);//5
			ny = y;//2
			mp[nx][ny] = ++cnt;
		}else{
			mp[nx][ny] = ++cnt;
		}
		x = nx;//4
		y = ny;//3
	}
	for(int i = 0;i < (2 * n - 1);i++){
		for(int j = 0;j < (2 * n - 1);j++){
			if(j == 0){
				cout << mp[i][j];
			} else{
				cout << " " << mp[i][j];
			}
		}
		cout << endl;
	}
	return 0;
}
上一篇:随机采样一致性算法(二)再遇


下一篇:CH2906 武士风度的牛(算竞进阶习题)