题目链接
今天做的第二题,感觉比较经典,详细记录一下吧!
Monkey and Banana
一个 n 阶方阵的元素是1,2,…,n^2,它的每行,每列和2条对角线上元素的和相等,这样
的方阵叫魔方。n为奇数时我们有1种构造方法,叫做“右上方” ,例如下面给出n=3,5,7时
的魔方.
3
8 1 6
3 5 7
4 9 2
5
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
7
30 39 48 1 10 19 28
38 47 7 9 18 27 29
46 6 8 17 26 35 37
5 14 16 25 34 36 45
13 15 24 33 42 44 4
21 23 32 41 43 3 12
22 31 40 49 2 11 20
第1行中间的数总是1,最后1行中间的数是n^2,他的右边是2,从这三个魔方,你可看出“右
上方”是何意。
Input
包含多组数据,首先输入T,表示有T组数据.每组数据1行给出n(3<=n<=19)是奇数。
Output
对于每组数据,输出n阶魔方,每个数占4格,右对齐".
Sample Input
2
3
5
Sample Output
8 1 6
3 5 7
4 9 2
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
题目大意:
一个 n 阶方阵的元素是1,2,…,n^2,它的每行,每列和2条对角线上元素的和相等,这样
的方阵叫魔方。n为奇数时我们有1种构造方法,叫做“右上方” ,例如下面给出n=3,5,7时
的魔方.
思路:
规律:在第一排,或者最后一列都需要特殊考虑(按照题目的规律来),除此之外 都是在当前位子的右上方填数,若其右上方已经填过数字 则跳到当前位子的下一个位子。
完整代码:
#include<stdio.h>
#include<string.h>
int map[22][22];
int main()
{
int i,j,k,n,t,cas;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
i=1;
j=(n+1)/2;
memset(map,0,sizeof(map));
map[i][j]=k=1;
while(k<=n*n)
{
if(i==1 && j!=n)//在 (1,j(j!=n)):跳到(n,j+1);
{
i=n;j++;
map[i][j]=++k;
}
else if(i==1 && j==n)//在(1,n):跳到(2,n);
{
i++;
map[i][j]=++k;
}
else if(j==n && i!=1)//在(i(i!=1),n):跳到(--i,1);
{
i--;j=1;
map[i][j]=++k;
}///以上为<span style="color:#ff0000;"><strong>特殊考虑</strong>,</span>
else if(i!=1 && j!=n)
{
if(map[i-1][j+1])//如果(i,j)的右上方填了数字,则跳到(--i,j);
{
i++;
map[i][j]=++k;
}
else //<span style="font-family: Arial, Helvetica, sans-serif;">如果(i,j)的右上方没有填数字,则跳到(--i,++j);</span>
map[--i][++j]=++k;
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
printf("%4d",map[i][j]);
printf("\n");
}
}
return 0;
}