这样的问题在我们中学时代玩的非常多,益智类的问题求解方法一直都是我们无聊课余娱乐的。
取一个值为1-n*n(n为奇数,求解奇阶幻方)放在一个n×n的方阵中,要求每行,每列的两个对角线的元素的和相同。
求解思路:
想起以前的做法,都是使用试探的方法去求解出来,但如果n的值太大时,放置的方法将为n*n的!种方法,显然我们以前的做法很难实现
查阅相关书籍吗,找到了一个可行的求解方法:
将1放在(1,(n+1)/2)的位置上,然后往左上的位置上放入下一个数,这种思想是将方阵卷成一个纸筒,知道n*n个元素全部放完为止。
注意,幻方的和是n*(n*n+1)÷2,例如三阶的幻方问题:幻方和为3×(3×3+1)÷2=15,
口诀摘要:
“1”坐边中间,斜着把数填;
出边填对面,遇数往下旋;
出角仅一次,转回下格间.
代码如下:
#include<iostream>
using namespace std;
#define N 5
int main(){
void magic(int n);
magic(5);
return 1;
}
void magic(int n){
int a[N][N];
int i=0;//空数组的第一行
int j=(n+1)/2;//空数组的中间列
//定义k为我们要放置的值
for(int k=1;k<=n*n;k++){
//开始放置
a[i][j]=k;
if(k%n==0){
i++;
}
//表示要斜跳行放置
else {
i=(i-1+n)%n;
j=(j-1+n)%n;
}
}
for(i=0;i<n;i++){
for(j=0;j<n;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}