|
题目描述
Apple最近迷上了做幻方,Apple还是个中高手,只要你说个奇数N就能把N*N的幻方做出来。其实你可以比他做得更好的。Apple总是画得很乱,而你可以利用程序排得很整齐^_^ 幻方的要求:每一行,每一列,还有两条斜线上数字的和都相等.
输入
每行一个奇数N(0< N < 30),输入0结束
输出
输入一个奇数,输出一个幻方,顺序参照样板输出;同一列的数右对齐,数与数用一个空格分开;输出完以后加一个回车。
样例输入
5
1
0
样例输出
11 18 25 2 9
10 12 19 21 3
4 6 13 20 22
23 5 7 14 16
17 24 1 8 15
1
解题思路
| 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 |
以上面这个5*5的幻方为例,先把1放置在第一行的最中间,然后接着2放在1的右上方,放置过程中会遇到的问题:
1) 如果超出上界,以上表1与2为例,将把2放置在最底层,也就是 i = i + n;
2) 如果超出右界,以上表3与4为例,将把4放置在最左层,也就是 j = j - n;
3) 如果既超出上界又超出右届,以上表16与17为例,执行1)、2)操作即可;
4) 如果碰到移动位置有数字存在,则按原位置向下走即可,如15和16。
对这个题目ac还有一点就是格式问题,输出是要求数据从后往前输出的,以及要求数字右对齐,如果忽略,很可能会错误。
以下是代码,以c为例:
#include<stdio.h>
int main()
{
int s[30][30] = { 0 };
int n, i = 1, j, k;
int j2, k2;
while (scanf("%d", &n) != EOF) {
if (n == 0)
break;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
s[i][j] = 0;
i = 1;
j = 0; k = (n - 1) / 2;
s[j][k] = i++;//先放第一个数
while (i <= n * n)
{
j = j - 1;
k = k + 1;
while (1) {
if (j >= 0 && k < n) { //不越界
if (s[j][k] != 0) { //该位置有数字
j = j2 + 1;
k = k2;
if (j == n) {
j = j - n;
}
continue;
}
else
break;
}
else if (j < 0 && k < n) //j越界
j = j + n; //换到底部
else if (j >= 0 && k >= n) //k越界
k = k - n;
else if (j < 0 && k >= n)//j、k同时越界
{
j = j + n;
k = k - n;
}
}
s[j][k] = i;
//记录上一次的下标
j2 = j;
k2 = k;
i++;
}
int c;
if (n*n < 10)
c = 1;
else if (n*n < 100)
c = 2;
else if (n*n < 1000)
c = 3;
for (i = n - 1; i >= 0; i--)
{
int j;
printf("%*d", c, s[i][0]);
for (j = 1; j < n; j++)
printf(" %*d", c, s[i][j]);
printf("\n");
}
printf("\n");
}
return 0;
}
|