温婉若妖

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

实现n阶幻方

n为奇数 (n=3,5,7,9,11……) (n=2*k+1,k=1,2,3,4,5……)

奇数阶幻方最经典的填法是罗伯特法(也有人称之为楼梯方)。填写方法是这样:

把1(或最小的数)放在第一行正中; 按以下规律排列剩下的n*n-1个数: 
(1)、每一个数放在前一个数的右上一格;
(2)、如果这个数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列; 
(3)、如果这个数所要放的格已经超出了最右列那么就把它放在最左列,仍然要放在上一行;
(4)、如果这个数所要放的格已经超出了顶行且超出了最右列,那么就把它放在前一个数的下一行同一列的格内; 
(5)、如果这个数所要放的格已经有数填入,处理方法同(4)。

这种写法总是先向“右上”的方向,象是在爬楼梯。

代码如下:

 1 // asdasdasdas.cpp : 定义控制台应用程序的入口点。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include <stdlib.h>
 6 
 7 int _tmain(int argc, _TCHAR* argv[])
 8 {
 9     //i为行 j为列 K即是小于n的平方的数
10 int a[20][20],i,j,k,n;
11 
12 printf("输入一个大于3小于20的的奇数");
13 scanf("%d",&n);
14 if((n<3)||(n%2==0)||(n>=20))
15 {
16     printf("输入错误!"); 
17 }
18 
19     for(i=1;i<=n;i++)
20         for(j=1;j<=n;j++)
21         a[i][j]=0;
22     j=n/2+1;
23     //第一行居中位置为1
24     a[1][j]=1;
25     for(k=2;k<=n*n;k++)
26      {
27          //向右上方移动 即行数减一 列数加一(从上到下 从左到右依次增大)
28         i=i-1;
29         j=j+1;
30         //判断是不是移动时同时超过了第一行和最右边那列,即过了对角线
31         if((i<1)&&(j>n))
32         {
33             //向下移动一行
34             i=i+2;
35             j=j-1;
36         }
37         else
38        {
39            //判断是不是过了第一行如果是就从最后一行开始
40             if(i<1)
41                 i=n;
42             //判断是不是过了最后一列如果是就从第一列开始
43             if(j>n)
44                 j=1;
45         }
46         //判断是不是要移动到的地方为空
47         if(a[i][j]==0)
48             a[i][j]=k;
49         //如果不是,和超过对角线处理方法一样 向下移动
50         //这里本来打算做成一个方法,这样两个就都能直接调用了
51         else
52          {
53             i=i+2;
54             j=j-1;
55             a[i][j]=k;
56         } 
57     }
58     //输出
59 for(i=1;i<=n;i++)
60      {
61     for(j=1;j<=n;j++)
62       printf("%4d",a[i][j]);
63     printf("\n");
64      }
65 system("pause");
66 }

 

 

 

posted on 2013-12-24 16:28  温婉若妖  阅读(293)  评论(0)    收藏  举报