输出魔方阵

一、实验目的

实验目的:练习多维数组的用法

二、实验原理

魔方阵,古代又称“纵横图”,是指组成元素为自然数1、2…n的平方的n×n的方阵,其中每个元素值都不相等,且每行、每列以及主、副对角线上各n个元素之和都相等。

魔方阵的排列方法

如3×3的魔方阵:

  8 1 6

  3 5 7

  4 9 2

  魔方阵的排列规律如下:

  (1)将1放在第一行中间一列;

  (2)从2开始直到n×n止各数依次按下列规则存放;每一个数存放的行比前一个数的行数减1,列数加1(例如上面的三阶魔方阵,5在4的上一行后一列);

  (3)如果上一个数的行数为1,则下一个数的行数为n(指最下一行);例如1在第一行,则2应放在最下一行,列数同样加1;

  (4)当上一个数的列数为n时,下一个数的列数应为1,行数减去1。例如2在第3行最后一列,则3应放在第二行第一列;

(5)如果按上面规则确定的位置上已有数,或上一个数是第一行第n列时,则把下一个数放在上一个数的下面。例如按上面的规定,4应该放在第1行第2列,但该位置已经被占据,所以4就放在3的下面;

要求:从键盘上输入一奇数n(0<n<16),输出n阶魔方阵。

三、主要数据结构和算法

1、数据结构的设计(写出构造的数据类型,即自己定义的结构体)

本实验没有用到自己定义数据类型

2、算法分析(算法用流程图或自然语言描述)

  判断输入的值是否属于0~16,先令所有元素都为0,判断j的位置,将1放在第一行中间一列,再从2开始处理,存放的行比前一个数的行数减1,列数加1,前一个数是第一行第n列时,把下一个数放在上一个数的下面,当行数减到第一行,返回到最后一行,当列数加到最后一行,返回到第一行,判断元素是否为零(是否位置被占),若被占,则该数放在上一个数的下面,若没有被占,继续正常运行,最后输出。

四、实验结果及分析

1、源程序(见附录)

2、测试结果截图 写出测试程序的数据,至少写三组数据,并把每组测试结果截图)

(1)第一组测试数据及结果截图

N=3

 

(2)第一组测试数据及结果截图

N=9

 

(3)第一组测试数据及结果截图

N=15

 

五、心得体会(自己在编程过程中对语法,写代码风格,实验本身的理解,以及以后写程序注意的问题)

1.用全体元素先赋值为0的方法,在后期判断是否还为0,来进一步判断未知是否被占;

2.考虑各种极端情况①位置被占;②行数减到第一行;③列数加到最后一行;④前一个数为第一行第n列;

3.先将1放好;

4.逐步细分,将各种特殊情况有条不紊的写进程序,理清思路;

#include<stdio.h> 
int main()
{int a[16][16],i,j,k,p,m,n;
p=1;
while(p==1)
   {
     scanf("%d",&n);
    if((n!=0)&&(n<=15)&&(n%2!=0))p=0;//判断输入的n是否为0~16; 
   }
for(i=1;i<=n;i++)
   for(j=1;j<=n;j++)
     a[i][j]=0;//先令所有的元素都为0; 
j=n/2+1;
a[1][j]=1;//将1放在第一行中间一列; 
for(k=2;k<=n*n;k++)//从第二行开始处理 
   {i=i-1;//存放的行比其前一个数的行数减1;
    
    j=j+1;//列数加1; 
    if((i<1)&&(j>n))// 前一个数是第一行第n列时,把下一个数放在上一个数的下面; 
      {i=i+2;
       j=j-1;
      }
    else
      {if(i<1)i=n;//当行数减到第一行,返回最后一行; 
       if(j>n)j=1;//当列数加到最后一行,返回第一行; 
      }
    if(a[i][j]==0)a[i][j]=k;//如果该元素为0,继续运行 
    else
      {i=i+2;
       j=j-1;
       a[i][j]=k;//否则该位置已被占,该数放在上一个数的下面; 
      }
    }
for(i=1;i<=n;i++)
   {for(j=1;j<=n;j++)
      printf("%5d",a[i][j]);
    printf("\n");
   }
}

 

posted @ 2021-06-02 14:33  烤山药护体  阅读(24)  评论(0编辑  收藏  举报