关于魔方阵的解法

2016-02-19 13:14 4 1 收藏

下面是个简单易学的关于魔方阵的解法教程,图老师小编详细图解介绍包你轻松学会,喜欢的朋友赶紧get起来吧!

【 tulaoshi.com - 编程语言 】

首先把从1~n2的整数按从小到大的顺序排列成一个n×n的方阵A进行观察。(本文中所有n都是指大于1的奇数,下文中均以“A”代表这类顺序排列的n×n方阵)
  以5阶阵为例:以下是A方阵
  1  2  3  4  5
  6  7  8  9  10
  11 12 13 14 15
  16 17 18 19 20
  21 22 23 24 25
  下边是魔方阵B:
  12 16 25 4  8
  6  15 19 23 2
  5  9  13 17 21
  24 3  7  11 20
  18 22 1  10  14
  先假设n阶奇次魔方阵B是存在的,从A中可以看出,B的任一元素在A中都有唯一确定的行号和列号组合(y,x)。
  分离出B中所有元素在A中的行号y来构成n×n方阵I,让I(i,j)等于从B(i,j)分离出来的y;(如I(1,1) =3,即12在A中的行号A(3,2);I(1,2)=4,即16在A中的行号A(4,1)。)以下是I方阵:
  3  4  5  1  2
  2  3  4  5  1
  1  2  3  4  5
  5  1  2  3  4
  4  5  1  2  3
  同样分离出B中所有元素在A中的列号y来构成n×n方阵J,让J(i,j)等于从B(i,j)分离出来的x。以下是J方阵
  2  1  5  4  3
  1  5  4  3  2
  5  4  3  2  1
  4  3  2  1  5
  3  2  1  5  4
  观察方阵I特征为:        1.组成方阵的数为1~n的整数;        2.任一行、列均遍历1~n的所有整数;        3.主对角线上的数均为(n+1)/2,辅对角线遍历1~n的所有整数。方阵J特征前两点同I,区别是第三点,辅对角线上的数均为(n+1)/2,主对角线遍历1~n的所有整数。 另外还有轻易忽略的一点,I、J方阵对应位置上的数字组合[I(i,j),J(i,j)]是唯一的。
         综合以上的结论可以知道:B(i,j)=(I(i,j)-1)×n+J(i,j)。所以只要构造出这样两个只含1~n的数的方阵I和J,就可以确定一个n×n的魔方阵。
  现在,问题就转化为怎样构造分别满足I和J的特征的两个n×n方阵。其实完成这样的算法是很简单的,可以按以下方法实现:1) 方阵I的第一行由(n+1)/2打头,后面依次为前一个数关于n的循环后继;2)方阵I的第i+1行由第i行循环右移得到。本人给出的程序:main()
  {
  int n,i,j;
  int a[20][20],x[20][20],y[20][20];/* a数组为最后结果数组文中的B方阵,X,Y分别是文中提到的数组I,J*/
  printf("please input the number:");
  scanf("%d",&n); /*输入需要的数组维数*/
   x[0][0]=(n+1)/2;
   for(j=1;jn;j++)
    {
     if(x[0][j-1]==n) x[0][j]=x[0][j-1]+1-n;
     else            x[0][j]=x[0][j-1]+1;
   }/*给x中的第一行元素赋值*/for(i=1;in;i++)
   for(j=0;jn;j++)
    {
      if(j-10) x[i][j]=x[i-1][j-1+n];
      else       x[i][j]=x[i-1][j-1];
  } /*通过变换给X的所有元素赋值*/
  clrscr();
  printf("X:");
  for(i=0;in;i++)
   for(j=0;jn;j++)
   {
   printf("%3d",x[i][j]);
   if(j==n-1)printf("");
   }/*输出X数组*/
  for(i=0;in;i++)
   for(j=0;jn;j++)
   y[i][j]=x[i][n-1-j];/*通过文中提到的公式给Y数组赋值*/
  printf("Y:");
  for(i=0;in;i++)
   for(j=0;jn;j++)
     {printf("%3d",y[i][j]);
     if(j==n-1)printf("");
     }/*输出Y数组*/
  for(i=0;in;i++)
   for(j=0;jn;j++)
     a[i][j]=(x[i][j]-1)*n+y[i][j];
  printf("A:");
  for(i=0;in;i++)
   for(j=0;jn;j++)
   {printf("%5d",a[i][j]);
   if(j==n-1)printf("");}
  /*输出A数组结果*/
    }

来源:http://www.tulaoshi.com/n/20160219/1603481.html

延伸阅读
标签: 手机游戏
《天天富翁》获得魔方的方法和魔方开启奖励规则 在《天天富翁》里难道除了充值和拼死做任务攒钻石,就没有什么方法可以在《天天富翁》里快速的获得高级角色和各种奖励呢?大家一定非常想知道吧?魔方算是游戏里的抽奖礼盒了,但是会等级的差别。约高级的魔方越难获得,但是奖励越好。今天就为大家介绍如何在 《天天富翁》里获得魔方和开启魔方 ...
这个魔方玩具是用木块和颜料制作而成的,不仅可以当魔方来玩,也可以用来当积木,堆积出各种不同造型的东西出来。 1、准备好27个正方体的小木块。 2、把颜料分别放到几个一次性的杯子中。 3、用画笔粘上颜料涂到小木块上,同一面的涂上同一种颜色,这样分别把八个面涂上6种不同的颜色。 这样就制作好了,等颜料干了后...
例如,如下的方阵:  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 顺时针旋转,却是如下结果: 13  9  5  1 14 10  6  2 15 11  7  3 16 12  8  4 代码如下: #include stdio.h void rotate(int* x, int rank) {  int* y = (i...
《魔方世界》入门攻略教程:职业技能武器物品及宠物表 《魔方世界》 入门指南教程,职业技能武器物品及宠物表。 关于按键 按F1可以看到键位信息 WASD移动 Q键使用消耗品 TAB键切换消耗品 R键使用场景道具/对话 SHIFT键行走模式 CTRL键爬墙...
标签: 数独 益智
摒除法 用数字去找单元内唯一可填空格,称为摒除法,数字可填唯一空格称为摒余解(隐性唯一解)。根据不同的作用范围,摒余解可分为下述三种:数字可填唯一空格在「宫」单元称为宫摒余解(Hidden Single in Box),这种解法称宫摒除法。数字可填唯一空格在「行」单元称为行摒余解(Hidden Single in Row),这种解法称行摒除法。数...

经验教程

15

收藏

32
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部