本文目錄一覽:
- 1、C語言填幻方(不要窮舉,要詳細講解)
- 2、怎樣用C語言編寫幻方
- 3、c語言程序設計——奇數階幻方的生成 利用二維數組
- 4、C++解決奇階幻方問題的方法
- 5、c語言程序設計–奇數階幻方的生成 利用二維數組
- 6、誰知道用C語言怎麼寫求幻方的程序?
C語言填幻方(不要窮舉,要詳細講解)
下面的夠詳細了吧
奇階幻方
當n為奇數時,我們稱幻方為奇階幻方。可以用Merzirac法與loubere法實現,根據我的研究,發現用國際象棋之馬步也可構造出更為神奇的奇幻方,故命名為horse法。
偶階幻方
當n為偶數時,我們稱幻方為偶階幻方。當n可以被4整除時,我們稱該偶階幻方為雙偶幻方;當n不可被4整除時,我們稱該偶階幻方為單偶幻方。可用了Hire法、 Strachey以及YinMagic將其實現,Strachey為單偶模型,我對雙偶(4m階)進行了重新修改,製作了另一個可行的數學模型,稱之為 Spring。YinMagic是我於2002年設計的模型,他可以生成任意的偶階幻方。
在填幻方前我們做如下約定:如填定數字超出幻方格範圍,則把幻方看成是可以無限伸展的圖形,如下圖:
Merzirac法生成奇階幻方
在第一行居中的方格內放1,依次向左上方填入2、3、4…,如果左上方已有數字,則向下移一格繼續填寫。如下圖用Merziral法生成的5階幻方:
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
loubere法生成奇階幻方
在居中的方格向上一格內放1,依次向右上方填入2、3、4…,如果右上方已有數字,則向上移二格繼續填寫。如下圖用Louberel法生成的7階幻方:
30 39 48 1 10 19 28
38 47 7 9 18 27 29
46 6 8 17 26 35 37
5 14 16 25 34 36 45
13 15 24 33 42 44 4
21 23 32 41 43 3 12
22 31 40 49 2 11 20
horse法生成奇階幻方
先在任意一格內放入1。向左走1步,並下走2步放入2(稱為馬步),向左走1步,並下走2步放入3,依次類推放到n。在n的下方放入n+1(稱為跳步),再按上述方法放置到2n,在2n的下邊放入2n+1。如下圖用Horse法生成的5階幻方:
77 58 39 20 1 72 53 34 15
6 68 49 30 11 73 63 44 25
16 78 59 40 21 2 64 54 35
26 7 69 50 31 12 74 55 45
36 17 79 60 41 22 3 65 46
37 27 8 70 51 32 13 75 56
47 28 18 80 61 42 23 4 66
57 38 19 9 71 52 33 14 76
67 48 29 10 81 62 43 24 5
一般的,令矩陣[1,1]為向右走一步,向上走一步,[-1,0]為向左走一步。則馬步可以表示為2X+Y,{X∈{[1,0], [-1,0]},Y∈{[0,1], [0,-1]}}∪{Y∈{[1,0], [-1,0]},X∈{[0,1], [0,-1]}}。對於2X+Y相應的跳步可以為2Y,-Y,X,-Y,X,3X,3X+3Y。上面的的是X型跳步。Horse法生成的幻方為魔鬼幻方。
Hire法生成偶階幻方
將n階幻方看作一個矩陣,記為A,其中的第i行j列方格內的數字記為a(i,j)。在A內兩對角線上填寫1、2、3、……、n,各行再填寫1、2、3、……、n,使各行各列數字之和為n*(n+1)/2。填寫方法為:第1行從n到1填寫,從第2行到第n/2行按從1到進行填寫(第2行第1列填n,第2行第n列填1),從第n/2+1到第n行按n到1進行填寫,對角線的方格內數字不變。如下所示為6 階填寫方法:
1 5 4 3 2 6
6 2 3 4 5 1
1 2 3 4 5 6
6 5 3 4 2 1
6 2 4 3 5 1
1 5 4 3 2 6
如下所示為8階填寫方法(轉置以後):
1 8 1 1 8 8 8 1
7 2 2 2 7 7 2 7
6 3 3 3 6 3 6 6
5 4 4 4 4 5 5 5
4 5 5 5 5 4 4 4
3 6 6 6 3 6 3 3
2 7 7 7 2 2 7 2
8 1 8 8 1 1 1 8
將A上所有數字分別按如下算法計算,得到B,其中b(i,j)=n×(a(i,j)-1)。則AT+B為目標幻方
(AT為A的轉置矩陣)。如下圖用Hire法生成的8階幻方:
1 63 6 5 60 59 58 8
56 10 11 12 53 54 15 49
41 18 19 20 45 22 47 48
33 26 27 28 29 38 39 40
32 39 38 36 37 27 26 25
24 47 43 45 20 46 18 17
16 50 54 53 12 11 55 9
57 7 62 61 4 3 2 64
Strachey法生成單偶幻方
將n階單偶幻方表示為4m+2階幻方。將其等分為四分,成為如下圖所示A、B、C、D四個2m+1階奇數幻方。
A C
D B
A用1至2m+1填寫成(2m+1)2階幻方;B用(2m+1)2+1至2*(2m+1)2填寫成2m+1階幻方;C用2*(2m+1)2+1至3*(2m+1)2填寫成2m+1階幻方;D用3*(2m+1)2+1至4*(2m+1)2填寫成 2m+1階幻方;在A中間一行取m個小格,其中1格為該行居中1小格,另外m-1個小格任意,其他行左側邊緣取m列,將其與D相應方格內交換;B與C接近右側m-1列相互交換。如下圖用Strachey法生成的6階幻方:
35 1 6 26 19 24
3 32 7 21 23 25
31 9 2 22 27 20
8 28 33 17 10 15
30 5 34 12 14 16
4 36 29 13 18 11
Spring法生成以偶幻方
將n階雙偶幻方表示為4m階幻方。將n階幻方看作一個矩陣,記為A,其中的第i行j列方格內的數字記為a(i,j)。
先令a(i,j)=(i-1)*n+j,即第一行從左到可分別填寫1、2、3、……、n;即第二行從左到可分別填寫n+1、n+2、n+3、……、2n;…………之後進行對角交換。對角交換有兩種方法:
方法一;將左上區域i+j為偶數的與幻方內以中心點為對稱點的右下角對角數字進行交換;將右上區域i+j為奇數的與幻方內以中心點為對稱點的左下角對角數字進行交換。(保證不同時為奇或偶即可。)
方法二;將幻方等分成m*m個4階幻方,將各4階幻方中對角線上的方格內數字與n階幻方內以中心點為對稱點的對角數字進行交換。
如下圖用Spring法生成的4階幻方:
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
YinMagic構造偶階幻方
先構造n-2幻方,之後將其中的數字全部加上2n-2,放於n階幻方中間,再用本方法將邊緣數字填寫完畢。本方法適用於n4的所有幻方,我於2002年12月31日構造的數學模型。YinMagic法可生成6階以上的偶幻方。如下圖用 YinMagic法生成的6階幻方:
10 1 34 33 5 28
29 23 22 11 18 8
30 12 17 24 21 7
2 26 19 14 15 35
31 13 16 25 20 6
9 36 3 4 32 27
魔鬼幻方
如將幻方看成是無限伸展的圖形,則任何一個相鄰的n*n方格內的數字都可以組成一個幻方。則稱該幻方為魔鬼幻方。
用我研究的Horse法構造的幻方是魔鬼幻方。如下的幻方更是魔鬼幻方,因為對於任意四個在兩行兩列上的數字,他們的和都是34。此幻方可用YinMagic方法生成。
15 10 3 6
4 5 16 9
14 11 2 7
1 8 13 12
羅伯法:
1居上行正中央,依次排開右上方。
右出格時寫最左,上出格時寫最下.
每逢幾個落一行.(幾個是幾*幾的方陣中的幾)
怎樣用C語言編寫幻方
你的這個問題實際上包括兩個問題:
1、幻方的算法
2、怎樣用C語言實現幻方的算法
這兩個問題是大不同的。
關於幻方的算法,或者叫幻方填法,目前有很多種,拉丁正交、馬步法等等,針對奇數或者偶數(又分單偶數和雙偶數)等有不同的算法,但這些算法只是幫你找到幻方的一個或多個實例(不會是全部),而同階數的幻方到底有多少個,那只有用窮舉法了,比如4階幻方,基本4階幻方共7040個,剔除旋轉翻轉的,即具有獨立結構的共880個;4階完美幻方共84個,具有獨立結構的共48個。
對於高階幻方(比如超過8階),窮舉法實際上是不可行的,因為它的窮舉時間將是天文數字(以目前主流PC),所以不要試圖用計算機窮舉高階幻方的全部結果,那將是徒勞的。
如果你只是需要1個實例,那麼推薦你使用MATLAB語言工具,因為它提供了幻方函數magic(n),不需要編程,直接從命令窗口輸入就可以得到答案。
至於第二個問題,當然你首先會C語言,剩下的就是編程技巧問題了,而這個問題是無從回答的。相信你問的是第一個問題。
以上的回答雖然沒有明確給出答案,但相信對你會有幫助。
c語言程序設計——奇數階幻方的生成 利用二維數組
#includestdio.h
void main()
{
int a[32][32],i,j,k,p,n;
p=1;
while(p==1)
{
printf(“Enter n(n=1~25)”);
scanf(“%d”,n);
if((n!=0)(n=25)(n%2!=0))
p=0;
}
for(i=1;i=n;i++)
for(j=1;j=n;j++)
a[i][j]=0;
j=n/2+1;
a[1][j]=1;
for(k=2;k=n*n;k++)
{
i=i-1;
j=j+1;
if((i1)(jn))
{
i=i+2;
j=j-1;
}
else
{
if(i1)
i=n;
if(jn)
j=1;
}
if(a[i][j]==0)
a[i][j]=k;
else
{
i=i+2;
j=j-1;
a[i][j]=k;
}
}
for(i=1;i=n;i++)
{
for(j=1;j=n;j++)
printf(“%d “,a[i][j]);
printf(“\n”);
}
}
做25*25以內的幻方
C++解決奇階幻方問題的方法
幻方最早記載於我國公元前500年的春秋時期《大戴禮》中,這說明我國人民早在2500年前就已經知道了幻方的排列規律。而在國外,公元130年,希臘人塞翁才第一次提起幻方。我國不僅擁用幻方的發明權,而且是對幻方進行深入研究的國家。公元13世紀的數學家楊輝已經編製出3-10階幻方,記載在他1275年寫的《續古摘廳算法》一書中。在歐洲,直到574年,德國著名畫家丟功才繪製出了完整的4階幻方。
數學上已經證明,對於n2,n階幻方都存在。目前填寫幻方的方法,是把幻方分成了三類,每類又有各種各樣的填寫方法。
1、奇數階幻方
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)。
這種寫法總是先向「右上」的方向,象是在爬樓梯。
2、雙偶階幻方
n為偶數,且能被4整除 (n=4,8,12,16,20……) (n=4k,k=1,2,3,4,5……)
先說明一個定義。互補:如果兩個數字的和,等於幻方最大數和最小數的和,即 n*n+1,稱為互補。
先看看4階幻方的填法:將數字從左到右、從上到下按順序填寫:
這個方陣的對角線,已經用顏色標出。將對角線上的數字,換成與它互補(同色)的數字。
這裡,n×n+1 = 4×4+1 = 17;把1換成17-1 = 16;把6換成17-6 = 11;把11換成17-11 = 6……換完後就是一個四階幻方。
對於n=4k階幻方,我們先把數字按順序填寫。寫好後,按4*4把它劃分成k*k個方陣。因為n是4的倍數,一定能用4*4的小方陣分割。然後把每個小方陣的對角線,象製作4階幻方的方法一樣,對角線上的數字換成互補的數字,就構成幻方。
3、單偶階幻方
n為偶數,且不能被4整除 (n=6,10,14,18,22……) (n=4k+2,k=1,2,3,4,5……)
這是三種裏面最複雜的幻方。
以n=10為例。這時,k=2
(1) 把方陣分為A,B,C,D四個象限,這樣每一個象限肯定是奇數階。用樓梯法,依次在A象限,D象限,B象限,C象限按奇數階幻方的填法填數。
(2) 在A象限的中間行、中間格開始,按自左向右的方向,標出k格。A象限的其它行則標出最左邊的k格。將這些格,和C象限相對位置上的數,互換位置。
(3) 在B象限任一行的中間格,自右向左,標出k-1列。(註:6階幻方由於k-1=0,所以不用再作B、D象限的數據交換),將B象限標出的這些數,和D象限相對位置上的數進行交換,就形成幻方。
看起來很麻煩,其實掌握了方法就很簡單了。
c語言程序設計–奇數階幻方的生成 利用二維數組
沒聽說過這個東西
但是在編程愛好者找到了一個
你看看行不行
main()
{ int i,j,n,k=1,a[N][N];
scanf(“%d”,n);
for(i=0;in;i++)
for(j=0;jn;j++)
a[i][j]=0;
a[i=0][j=n/2]=k;
for(k=2;k=n*n;k++)
{ i-=1;j+=1;
if(i==-1j!=n) {i=n-1;a[i][j]=k;}
else if(j==ni!=-1) {j=0;a[i][j]=k;}
else if((i==-1j==n)||a[i][j]!=0) {i+=2;j-=1;a[i][j]=k;}
else a[i][j]=k;
}
for(i=0;in;i++)
{ for(j=0;jn;j++)
printf(“%3d”,a[i][j]);
printf(“\n”);
}
printf(“\n”);
}
誰知道用C語言怎麼寫求幻方的程序?
#include stdio.h
#include stdlib.h
#include math.h
#include conio.h
#define MAX_INDEX 100
void swap(int *a,int *b)
{
int t;
t=*a;
*a=*b;
*b=t;
}
/*快速排序算法*/
void QuickSort(int a[], int l, int r)
{
int i=l; /*從左至右的游標*/
int j=r + 1; /*從右到左的游標*/
int pivot=a[l];
if (l = r) return;
/*把左側= pivot的元素與右側= pivot 的元素進行交換*/
while (1)
{
do
{/*在左側尋找= pivot 的元素*/
i = i + 1;
} while (a[i] pivot);
do
{/*在右側尋找= pivot 的元素*/
j = j – 1;
} while (a[j] pivot);
if (i = j) break; /*未發現交換對象*/
swap(a[i],a[j]);
}
/*設置p i v o t*/
a[l] = a[j];
a[j] = pivot;
QuickSort(a, l, j-1); /*對左段排序*/
QuickSort(a, j+1, r); /*對右段排序*/
}
void Huanf(int Array[][MAX_INDEX],int n)
{
int i,j;
int a,b,m;
int tempArray1[MAX_INDEX];
int tempArray2[MAX_INDEX];
a=n/2;
b=a+1;
m=n%4;
switch(m)
{
case 0:
case 2:
/*穿心對調*/
for(i=0;in;i++)
for(j=0;jn/2;j++)
{
if(in/2)
{
if(i%2==1Array[i][j]%2==0)/*偶行換偶*/
{
swap(Array[i][j],Array[n-1-i][n-1-j]);
}
else if(i%2==0Array[i][j]%2==1)/*奇行換奇*/
{
swap(Array[i][j],Array[n-1-i][n-1-j]);
}
}
else
{
if(i%2==1Array[i][j]%2==1)/*偶行換奇*/
{
swap(Array[i][j],Array[n-1-i][n-1-j]);
}
else if(i%2==0Array[i][j]%2==0)/*奇行換偶*/
{
swap(Array[i][j],Array[n-1-i][n-1-j]);
}
}
}
/*End穿心對調*/
if(m==2)
{
for(i=0;in/2;i++)
{
if((i!=0)(i!=a-1)(i!=b-1)(i!=n-1))
{
swap(Array[i][a-1],Array[n-1-i][a-1]);
swap(Array[b-1][i],Array[b-1][n-1-i]);
}
}
swap(Array[0][a-1],Array[0][b-1]);
swap(Array[a-1][0],Array[b-1][0]);
swap(Array[2][0],Array[2][n-1]);
swap(Array[0][2],Array[n-1][2]);
}
break;
case 1:
case 3:
/*穿心對調*/
for(i=0;in;i++)
for(j=0;jn/2;j++)
{
if(in/2)
{
if(i%2==1Array[i][j]%2==0) /*偶行換偶*/
{
swap(Array[i][j],Array[n-1-i][n-1-j]);
}
else if(i%2==0Array[i][j]%2==0)/*奇行換奇*/
{
swap(Array[i][j],Array[n-1-i][n-1-j]);
}
}
else if(in/2)
{
if(i%2==1Array[i][j]%2==0)/*偶行換偶*/
{
swap(Array[i][j],Array[n-1-i][n-1-j]);
}
else if(i%2==0Array[i][j]%2==0)/*奇行換奇*/
{
swap(Array[i][j],Array[n-1-i][n-1-j]);
}
}
}
/*End穿心對調*/
/*重排米字*/
for(i=0;in;i++)
{
tempArray1[i]=Array[i][i];
tempArray2[i]=Array[a][i];
}
QuickSort(tempArray1,0,n-1);
QuickSort(tempArray2,0,n-1);
for(i=0;in;i++)
{
Array[i][i]=tempArray2[i];
Array[a][i]=tempArray1[i];
}
for(i=0;in;i++)
{
tempArray1[i]=Array[i][n-1-i];
tempArray2[i]=Array[i][a];
}
QuickSort(tempArray1,0,n-1);
QuickSort(tempArray2,0,n-1);
for(i=0;in;i++)
{
Array[i][n-1-i]=tempArray2[i];
Array[i][a]=tempArray1[i];
}
/*End重排米字*/
if(m==3)
{
for(i=0;in/2;i++)
{
if((i!=a-1)(i!=b-1)(i!=a+1))
{
swap(Array[i][a-1],Array[n-1-i][a-1]);
swap(Array[a-1][i],Array[a-1][n-1-i]);
}
}
swap(Array[a-1][a-1],Array[a+1][a+1]);
swap(Array[a-1][b-1],Array[a+1][b-1]);
}
break;
default:
break;
}
return;
}
void main()
{
int Ne[MAX_INDEX][MAX_INDEX];
int i,j,n;
while(1)
{
printf(“Please Input N (0 quit): “);
scanf(“%d”,n);
if(n==0)
break;
/*數組賦初值*/
for(i=0;in;i++)
for(j=0;jn;j++)
Ne[i][j]=i*n+(j+1);
Huanf(Ne,n);
for(i=0;in;i++)
for(j=0;jn;j++)
{
printf(“%-4d”,Ne[i][j]);
if(j==n-1)
printf(“\n\n”);
}
printf(“\n\n”);
getch();
}
}
原創文章,作者:KZDO,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/143414.html