C++帮忙解释一下代码的思想。。。

ProblemDescription猪最近迷上了做幻方,猪还是个中高手,只要你说个奇数N,他就能把N*N的幻方做出来。其实你可以比他做得更好的。猪总是画得很乱,而你可以利... Problem Description猪最近迷上了做幻方,猪还是个中高手,只要你说个奇数N,他就能把N*N的幻方做出来。其实你可以比他做得更好的。猪总是画得很乱,而你可以利用程序排得很整齐^_^ 幻方的要求:每一行,每一列,还有两条斜线上数字的和都相等。 Input每行有一个数N(0< N < 30),输入0结束。 Output输入一个奇数,输出一个幻方,每个数占3格,顺序参照样板输出,输出完以后加一个回车。 Sample Input5
1
0

Sample Output11 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代码如下#include <stdio.h>
#include <string.h>
int f[30][30];int main()
{
int n;
while(scanf("%d",&n)&&n)
{
memset(f,0,sizeof(f));
int i,j,t=1,k,m;
i=n;
j=(n+1)/2;
f[i][j]=1;
for(t=2; t<=n*n; t++)
{
k=i,m=j;
i++;
j++;
if(i>n && j>n) i=1,j=1;
else if(i>n) i=1;
else if(j>n) j=1;
if(f[i][j]) i=k-1,j=m;
f[i][j]=t;
}
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
printf("%3d",f[i][j]);
puts("");
}
puts("");
} return 0;
}
展开
 我来答
hacker_win7
2012-11-19 · 超过14用户采纳过TA的回答
知道答主
回答量:25
采纳率:100%
帮助的人:28万
展开全部
幻方又叫魔方

在这里我先来说说奇数幻方的特征:
1。1的位置可以在第一行中间位置 或 最后一行的中间位置
2。N*N幻方所填的数是从1 到 N*N
3。当幻方确定填写1的位置后,接下来的2(即下一个数)的位置在1的位置的右下方
如果有越界情况回到第一行或第一列,如你上面样例中的2的位置是(1,4)(第1行,第4列)
而1的位置是(5,3) 右下的位置应该是(6,3),由于6超过了最大行数5,那么置为1,
即为(1,4)(其实就是一个循环)。同理3的位置就是 (1+1,4+1) 即(2,5)。
接下来是4的位置就是(3,1) ,5的位置是(4,2)。再接下来是6的位置 ,应该是(5,3)
但这里1已经占用来了这个位置,所以从这个数的右下改成正上方 及6的位置为(4-1,2)即
(3,2)。按此规则不断循环,直到将所有的数填完为止。

接下来分析你给的程序的思想。我仅分析核心的填数的思想,剩下的输入输出将不予讨论:
i=n;
j=(n+1)/2;
f[i][j]=1;
for(t=2; t<=n*n; t++)
{
k=i,m=j;
i++;
j++;
if(i>n && j>n) i=1,j=1;
else if(i>n) i=1;
else if(j>n) j=1;
if(f[i][j]) i=k-1,j=m;
f[i][j]=t;
}

以上为核心代码:
i=n;
j=(n+1)/2;
f[i][j]=1;
这几句是将初始位置1填到最后一行的中间
for(t=2; t<=n*n; t++)

循环,将剩下的2到n*n的所有数填入。
k=i,m=j;//保存当前位置,因为后面如果出现已占用情况还要用到这个坐标的正上方

i++;
j++;
默认先寻找当前位置的右下方
if(i>n && j>n) i=1,j=1;
else if(i>n) i=1;
else if(j>n) j=1;
如果出现越界情况 那么把越界情况的那一维置为1
if(f[i][j]) i=k-1,j=m;//是否已占用,如果占用就用保存的当前位置的正上方,注意初始化的memset(f,0,sizeof(f));,0表示未填数,非0表示已有数填入

f[i][j]=t;//在最终确定下来的位置填入数,然后t++ 继续填下一个数,同时 i, j 保存着当前已填的位置

这样循环完后便将所有数填入

幻方的特征满足 行 列 斜线 和 相等的条件。
百度网友c3803493e
2012-11-23 · 超过20用户采纳过TA的回答
知道答主
回答量:35
采纳率:100%
帮助的人:42万
展开全部

我用图解得方式把思路说一下,

代码我想已经看懂了,但是不明白原理吧?

那么我就跑开代码,给个思路:

1)在幻方中,所有的数都不相同

2)行列全部相同

这里就包含了一个重要的条件,如果这边数字为小,那么那边数字必然为大.

根据这个原理,又总结了规律,发现如下:

以3x3为例子:

.  .  .

.  .  .

.  1  .


.  .  2

.  .  .

.  1  .     行= 行+1, 列 = 列+1; 超过的从1开始


.  .  2     同理 1= 1+1, 3 = 3+1; 超过的从1开始

3  .  .

.  1  .


我用箭头标出来,你就懂了

4  9  2

3  5  7

8  1  6


这是一个很巧妙的构思,那么在3x3下面就是这样

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式