产生任意奇数阶幻方 三种方法实现

1.       幻方矩阵

幻方是一种很有意思的数字矩阵,在很早著名的九宫八卦阵就与幻方有关。

幻方的定义为:

1 到 N*N 的整数填入N*N的方格中,每行和每列以及对角线的数字之和必须是相等的。

你作为八卦公司的顶级程序员,现在需要你解决一个问题,将任意奇数阶的幻方找出来。

 

输入:

 

输入包括多个测试集,每行为一个正奇数N(1<= N < 1000),0作为输入的结束且不需要处理。

 

输出:

 

对于输入的每一个N, 输出一个它所对应的N阶幻方,如果存在多个,任意一个即可。

每个幻方为N*N的矩阵,

对于每个幻方,每行输出幻方的一行,每行中的数字之间用一个或多个空格分开。不同的幻方之间用一个空行分开。

 

算法思路:

 

该题也采用了三种方法实现。

主界面:

 

Merzirac法生成奇阶幻方

算法思想:

在第一行居中的方格内放1,依次向右上方填入2、3、4…,如果右上方已有数字,则向下移一格继续填写。

 

输入1:产生一个5*5魔方,此魔方是固定的。可以改变宏定义中的N产生任意奇数阶魔方。

 

 

 

loubere法生成奇阶幻方。

算法思想:

在居中的方格向上一格内放1,依次向右上方填入2、3、4…,如果右上方已有数字,则向上移二格继续填写

 

 

输入2:产生一个5*5魔方,此魔方是固定的。可以改变宏定义中的N产生任意奇数阶魔方。

 

 

 

 

 

 

 

 

 

 

 

 

horse法生成奇阶幻方。

算法思想:

先在任意一格内放入1。向左走1步,并下走2步放入2(称为马步),向左走1步,并下走2步放入3,依次类推放到n。在n的下方放入n+1(称为跳步),再按上述方法放置到2n,在2n的下边放入2n+1。

 

 

 

输入3:提示,输入一个数据,此时输入的数据表示随机产生多少个不同的奇幻方,同时也可以改变宏定义中的N产生奇幻方。

 

输入0:任意键退出。

附件:

#include<stdio.h>

#include<windows.h>

#include <time.h>

void Merziracmagic();

void MagicHorseRandom();//随机化方法

void louberemagic();

int num(int number);     //MagicHorseRandom()随机化方法产生的幻方个数

int menu_select() ;

 

#define N 5     //幻方必为奇数

 

int menu_select()   

{

  char c;

 

 //system("cls");/*运行前清屏*/

 printf("\t\t**** 魔方 Author byYongLiu ****\n");

 printf("\t\t  1. Merziracmagic魔方 |\n");

 printf("\t\t  2. louberemagic魔方|\n");

 printf("\t\t  3. MagicHorseRandom魔方|\n");

 printf("\t\t  0. 退出 |\n");

 printf("\t\t*****************************************\n");

 printf("\t\t\t请选择(0-3):");

 

  do{

     c=getchar(); /*读入选择*/

  }while(c<'0'||c>'3');

  return(c-'0'); /*返回选择*/

}

 

int main()

{

 

  int number;

  for(;;)

         {

      switch(menu_select())/*选择判断*/

                   {

          case 1:

          printf("\t\t1. Merziracmagic魔方 |\n");

          Merziracmagic();

          break;

 

     

          case 2:

          printf("\t\t2. louberemagic魔方|\n");

          louberemagic();

          break;

 

    

          case 3:

          printf("\t\t3. MagicHorseRandom魔方|\n");

          printf("\t\tpleaseinput the number of magic ");

                     scanf("%d",&number);

                     num(number);//随机化方法

          printf("\t\t\t");

        

          break;

 

 

          case 0:

          printf("\t\t\t结束退出!\n"); /*结束程序*/

          printf("\t\t\t");

          system("pause");

          exit(0);

                   }       

         }

}

 

 

 

int num(int number)

{

         inti=0;

         intcount=0;

         srand((int)time(NULL));

         while(++count<=number)

         {

           printf("\t\t%d.\n",++i);

           MagicHorseRandom();

         }

         return1;

}

 

void MagicHorseRandom()

{

    inta[N+1][N+1]={0};//对其初始化

 

         inti=rand()%N+1;  //ij随机在1到N*N中选取

         intj=rand()%N+1;

    //printf("%2d\n",i);

    //printf("%2d\n",j);

         a[i][j]=1;          

         for(intk=2;k<=N*N;k++)

         {

           int row=i;

           int col=j;

 

           ++j;                 //向右走一步

           if(j>N)

                     j=1;

           ++i;                 //向下走一步

           if(i>N)

                     i=1;

 

           ++i;                 //向下走一步

           if(i>N)

                     i=1;

          

      if(a[i][j]==0)      //如果右上方没有元素填写进去

                     a[i][j]=k;

           else

           {

        

                     i=row; //记住下标

                     j=col;

                     i++;

                     if(i>N)

                              i=1;

 

                    

                     a[i][j]=k;

           }

         }

 

         for(i=1;i<=N;i++)

         {

                   printf("\t\t");

                   for(j=1;j<=N;j++)

                   {

                            printf("  %3d",a[i][j]);

                           

                   }

             printf("\n");

         }

 

         printf("\n");

         printf("\n");

 

}

 

 

//Merzirac法生成奇阶幻方

//在第一行居中的方格内放1,依次向右上方填入2、3、4…,如果右上方已有数字,则向下移一格继续填写。

 

void Merziracmagic()

{

         inta[N+1][N+1]={0};//对其初始化

         inti=1,j=(N+1)/2;

         a[i][j]=1;           //第一行中间元素置为1

         for(intk=2;k<=N*N;k++)

         {

           int row=i;

           int col=j;

           --i;

           ++j;                 //连续填写右上方元素

           if(i==0)

                     i=N;

           if(j>N)

                     j=1;

      if(a[i][j]==0)      //如果右上方没有元素填写进去

                     a[i][j]=k;

           else

           {

 

                     i=row; //记住下标

                     j=col;

                     i++;

                     if(i>N)

                              i=1;

 

                    

                     a[i][j]=k;

           }

         }

 

         for(i=1;i<=N;i++)

         {       

                   printf("\t\t");

                   for(j=1;j<=N;j++)

                   {

                            printf("  %3d",a[i][j]);

                           

                   }

             printf("\n");

         }

         printf("\n");

         printf("\n");

 

}

 

 

//loubere法生成奇阶幻方

//在居中的方格向上一格内放1,依次向右上方填入2、3、4…,如果右上方已有数字,则向上移二格继续填写。

void louberemagic()

{

         inta[N+1][N+1]={0};//对其初始化

         inti=(N+1)/2-1,j=(N+1)/2;

         a[i][j]=1;           //最中间元素的上一层

         for(intk=2;k<=N*N;k++)

         {

           int row=i;

           int col=j;

           --i;

           ++j;                 //连续填写右上方元素

           if(i==0)

                    i=N;

           if(j>N)

                    j=1;

      if(a[i][j]==0)      //如果右上方没有元素填写进去

                     a[i][j]=k;

           else

           {

 

                     i=row; //如果采用回溯的方法考虑的问题比较多,还是记住下标

                     j=col;

 

                     i--;

                     if(i==0)

                             i=N;

                     i--;

 

                     if(i==0)

                             i=N;

 

                    

                     a[i][j]=k;

           }

         }

 

         for(i=1;i<=N;i++)

         {       

                   printf("\t\t");

                   for(j=1;j<=N;j++)

                   {

                            printf("  %3d",a[i][j]);

                           

                   }

             printf("\n");

         }

         printf("\n");

         printf("\n");

 

}

 注:代码上传在http://download.csdn.net/detail/liuyongvs2009/7077279

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值