幻方算法

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

幻方算法

首先,奇数的幻方,第一行中间放1,然后依次2、3、4一直往右上填,越界则反向,如果该位置有了数字,则排在前一个数的下面。原则:非右上则下

其次,4的倍数的的幻方。设N%4等于0,则以每个4*4画对角,不在对角线上的数字与相对应数字对换。

比如8*8的,(0,1)与(7,6)对换,类推。原则:横竖下标对N比余,相等或相加等于3则忽略,不做对换

最后,最复杂的最后一种情况,单偶数的幻方。我找了资料,但是没有完全好用的,总有缺陷

概念:N=4m+2

方法1:

AC

DB

按上图将其分为4个部分,分别填入1-N*N/4组成的奇数幻方,N*N/4+1-N*N/2组成的奇数幻方,N*N/2+1-N*N/4*3组成的奇数幻方,N*N/4*3-N*N组成的奇数幻方

将AD中m列互换。不是镜面互换,而是平移。

将BC中m-1列互换,同上。

方法2:LUX法

L U X

41 14 14

23 23 32

先做一个N/2的奇数幻方,然后把这个幻方的每个数x替换成一个田字的四个数(x-1)*4+1——x*4

这四个数的排列顺序有3种,前m+1行的按L排列,后m-1行的按X排列,中间一行中间一列按L排列,其余的按U排列。

下面是我写的JAVA实现类,2种单偶数我都实现了(第一种方法的实现被我注释掉了),还有一个监测的方法,仅供参考。

public class HuanClass {

private int N;

private int SUM;

private int MAX;

private int[][] RE;

public HuanClass(int val) throws Exception{

N=val;

MAX=N*N;

if(MAX%2==1)SUM=(MAX+1)/2*N;

else SUM=(MAX+1)*N/2;

RE=new int[N][N];

if(N<3)

throw new Exception("shit");

else if(N%2==1)

RE=CountOdd(N);

else if(N%4==0)

CountFour();

else

CountEven();

}

private int[][] CountOdd(int n){

int[][] IRE=new int[n][n];

int i=0;

int j=n/2;

int tmp=1;

while(true){

if(j>=n)j=0;if(i<0)i=n-1;

if(IRE[i][j]==0){IRE[i--][j++]=tmp++;}

else{i+=2;j--;if(j<0)j=n-1;if(i>=n)i=i%n;

if(IRE[i][j]==0)IRE[i--][j++]=tmp++;

else break;

}

}

return IRE;

}

private void CountFour(){

int fillCount=1;

for(int i=0;i

for(int j=0;j

RE[i][j]=fillCount;

fillCount++;

}

}

int tmp;

for(int i=0;i

for(int j=0;j

if(i%4!=j%4&&(j%4+i%4)!=3){

tmp=RE[i][j];

RE[i][j]=RE[N-i-1][N-j-1];

RE[N-i-1][N-j-1]=tmp;

}

}

}

}

/*

private void CountEven(){

int halfN=N/2;

int[][] tmpIArr=CountOdd(halfN);

for(int i=0;i

for(int j=0;j

RE[i][j]=tmpIArr[i][j];

RE[i+halfN][j]=tmpIArr[i][j]+halfN*halfN*3;

RE[i][j+halfN]=tmpIArr[i][j]+halfN*halfN*2;

RE[i+halfN][j+halfN]=tmpIArr[i][j]+halfN*halfN; }

}

int m=(halfN-1)/2;

int tmp;

for(int j=0;j

for(int i=0;i

tmp=RE[i][j];

RE[i][j]=RE[i+halfN][j];

RE[i+halfN][j]=tmp;

if(j

tmp=RE[i][j+halfN];

RE[i][j+halfN]=RE[i+halfN][j+halfN];

RE[i+halfN][j+halfN]=tmp;

}

}

}

}*/

private void CountEven(){

int halfN=N/2;

int m=(halfN-1)/2;

int[][] Seq=CountOdd(halfN);

char[][] SeqSign=new char[halfN][halfN]; for(int i=0;i

for(int j=0;j

}

}

int i=halfN-1;

for(int l=1;l

for(int j=0;j

SeqSign[i][j]='X';

}

}

for(int j=0;j

if(j==halfN/2)

SeqSign[i][j]='L';

else

SeqSign[i][j]='U';

}

for(i=0;i

for(int j=0;j

int beginNum=(Seq[i][j]-1)*4;

switch (SeqSign[i][j]){

case 'L':

RE[i*2][j*2]=beginNum+4;

RE[i*2+1][j*2]=beginNum+2;

RE[i*2][j*2+1]=beginNum+1;

RE[i*2+1][j*2+1]=beginNum+3;

break;

case 'U':

RE[i*2][j*2]=beginNum+1;

RE[i*2+1][j*2]=beginNum+2;

RE[i*2][j*2+1]=beginNum+4;

RE[i*2+1][j*2+1]=beginNum+3;

break;

case 'X':

RE[i*2][j*2]=beginNum+1;

RE[i*2+1][j*2]=beginNum+3;

RE[i*2][j*2+1]=beginNum+4;

相关文档
最新文档