奇数阶魔方阵
Time Limit: 1 second
Memory Limit: 50 MB
【问题描述】
魔阵是用自然数1,2,3…,n平方(n为奇数),填n阶方阵的各个元素位置,使方阵的每行的元素之和、每列元素之和及主对角线元素之和均相等。奇数阶魔阵的一个算法是将自然数数列从方阵的中间一行最后一个位置排起,每次总是向右上角排(即A[i,j]的下一个是A[i-1,j+1])。但若遇以下四种情形,则应修正排数法:(1) 列排完(即j>n时),则转排第一列;
(2) 行排完(即I<1时),则转排第n行(最后一行);
(3) 若Aij已排进一个自然数,则排原数所在位置的左边一个格子,Ai,j-1。
例如3阶方阵,则按上述算法可排成:
2 7 6
9 5 1
4 3 8
【输入】
共1行,一个小于100的正奇数;
【输出】
包含n行的魔方阵,如果输入为偶数则输出“error!”,输出最后以换行结束
【输入样例】
5
【输出样例1】
每个数的输出场宽为“5” 9 3 22 16 15 2 21 20 14 8 25 19 13 7 1 18 12 6 5 24 11 10 4 23 17
【题解】
这道题看似很复杂,其实只是一道简单的模拟题。题意大概就是说从中间一行的最后一个数开始不断地往右上角取数。在取的时候如果越过边界就有相应地改变规则。就是这样吧。没什么好说的。
【代码】
#include <cstdio> #include <stdlib.h> const int maxn = 100; int n,a[maxn+10][maxn+10]; void input_data() { scanf("%d",&n); if ( (n % 2) == 0) //n为偶数的时候要判错 { printf("error!"); exit(0); } } void get_ans() { for (int i = 1;i <= n;i++) for (int j = 1;j <= n;j++) //初始化一下。 a[i][j] = 0; int m = (n / 2) + 1; //获取中间的那一行 int i = m,j = n; int now = 1,d = n*n + 1; while (now !=d) //这是结束取数的条件 { a[i][j] = now++; int ti = i-1,tj = j+1; if (ti < 1) ti = n; if (tj >n ) tj = 1; //先预取一下数 if (a[ti][tj] != 0) //如果下一个要取的地方已经放有数字 那么就到原来数字的左边. { j = j-1; if (j < 1) j = n; } else //没有数字的话就在那里取一个数字。 { i = ti; j = tj; } } } void output_ans() { for (int i = 1;i <= n;i++) { for (int j = 1;j <= n;j++) printf("%5d",a[i][j]); //场宽如此设置。 printf(" "); } } int main() { input_data(); get_ans(); output_ans(); return 0; }