tft每日頭條

 > 生活

 > 奧數九宮格怎麼分析

奧數九宮格怎麼分析

生活 更新时间:2024-07-31 12:28:56

九宮算是指在3*3個方格中,每個方格分别放入1個數,這個數必須是1-9中之一,每個數必須而且隻能放入一次。要求3*3方格中每一行、每一列、兩條對角線的三個數之和都相等。

五階幻方是指在5*5個方格中,每個方格各放入一個數,這個數必須是1-25中之一,每個數必須而且隻能放入一次。要求5*5方格中每一行、每一列、兩條對角線的五個數之和都相等。

原以為奇數階幻方中,正中間的方格應該填入數列中的中位數,例如在3階幻方中,正中間的方格應該填入9,但是在5階幻方中,這個假設就失效了,下面是具體的例子。

奧數九宮格怎麼分析(奧數中九宮算升級版)1

奧數九宮格怎麼分析(奧數中九宮算升級版)2

正中間的單元格一個是10,一個是9,都不是13。

下面的這個例子是從網上找到的五階幻方求解的源程序,采用逐步搜索的方法,求得所有解。我最長運行了3小時,求得了大約29萬種不同解,不知道全部有效解一共是多少?

#include "stdio.h" #define LENGTH 10 #define SIZE LENGTH*LENGTH int a[LENGTH][LENGTH],b[SIZE],degree,number=0,max,sum; int main() { int i=0,j=0,m,temp,n,x,k,y,h,z; printf("please input a degree:"); scanf("%d",°ree); max=degree*degree; sum=(max 1)*degree/2; for(i=1;i<=degree;i ) { b[i]=0; //1-5标記為沒有選中,因為0不是目标數字,所以i從1開始 //b[]可能代表某一行的5個數 for(j=0;j<degree;j ) { a[i-1][j]=0; //目标數組全部置為0,行标從0開始,列标也從0開始 } } //全部賦0值 i=j=z=0; while(1) //大循環開始 { temp=a[i][j]; a[i][j]=0; //把a[i][j]讀出來,賦值給temp,然後将a[i][j]置為0 //a[][]為目标數組 for(m=temp 1 z,z=0;m<=max;m ) { if(b[m]==0) { if(temp!=0) { b[temp]=0; temp=0; } if(i<degree-2 && j<degree-2) //是否進入第三行、第三列 { if(i==degree-3) //行判斷,是不是第三行 { for(n=0,x=0;n<i;n ) { x =a[n][j]; } x =m; //x為已知數的和 k=sum-x; //K為剩餘數的和 if(k>max max-1 || (k==max max-1 && (b[max]==1 || b[max-1]==1))) //剩餘的數字已無可能 { continue; } if(k<3 || (k==3 && (b[1]==1 && b[2]==1))) //剩餘的數字已無可能 { m=max 1; break; } } if(j==degree-3) //列判斷,是不是第三列 { for(n=0,x=0;n<j;n ) { x =a[i][n]; //x為該行已選數字之和 } x =m; //m為該行第三列待選數字 k=sum-x; //某列已選好的數字求和,沒選的數字求和 if(k>max max-1 || (k==max max-1 && (b[max]==1 || b[max-1]==1))) //還剩2個數沒有選,如果k值大于最大兩個數之和,表示沒有可能;如果等于最大兩個數之和,但是最大兩個數其中之一已經用過了,表示沒有可能。 { continue; } if(k<3 || (k==3 && (b[1]==1 && b[2]==1))) //最小情況判斷,比3還小不可能,等于3但是1,2其中之一已被選擇,也不可能 { m=max 1; break; } } //将M賦值給數組a,同時标記數組b,該數字已使用 a[i][j]=m; b[m]=1; j ; break; } if(j==degree-2) //該行已經選了3個數,準備選第四個數 { for(n=0,x=0;n<j;n ) { x =a[i][n]; //前面的數求和 } x =m; //和值加入dm k=sum-x; //剩餘的值 if(k>0 && k<=max && m!=k && b[k]==0) //剩餘的值在最大和最小之間,m與k不相等,k值沒有被選過 { a[i][j]=m; b[m]=1; a[i][j 1]=k; b[k]=1; //最後2個數字,一起完成賦值 if(i<degree-2) //如果還剩超過2行,則進入下一行 { i ; j=0; break; } } else { if(i==degree-2 && j==1) { j--; b[a[i 1][j]]=0; a[i 1][j]=0; break; } else { continue; } } } if(i==degree-2) { //還剩2行 for(n=0,x=0;n<i;n ) { x =a[n][j]; } x =m; k=sum-x; //前幾行求和,另外得出剩下幾行的和 if(k>0 && k<=max && m!=k && b[k]==0) { //k的值在最大]、最小之間,m、k對應的值沒有被用過 if(j<degree-2) { if(j==0) { for(n=0,x=degree-1,y=0;n<i;n ) { y =a[n][x--]; //對角線求和 } y =k; h=sum-y; //對角線已選值的和,以及剩餘的值的和 if(h>0 && h<=max && h!=k && h!=m && b[h]==0) { //對角線的判斷 a[i][j]=m; b[m]=1; a[i 1][j]=k; b[k]=1; z=h-1; //該行,和下一行的值複制 j ; break; } else { continue; } } if(j==1) { for(n=0,x=degree-1,y=0;n<i;n ) { y =a[n][x--]; } y =(a[degree-1][0] m); if(y!=sum) { //值不滿足65,重新歸零 b[a[degree-1][0]]=0; a[degree-1][0]=0; j--; break; } } a[i][j]=m; b[m]=1; a[i 1][j]=k; b[k]=1; j ; break; } else if(j==degree-2) { for(n=0,x=0;n<=i;n ) { x =a[n][n]; } h=sum-x; if(h>0 && h<=max && h!=m && h!=k && b[h]==0) { for(n=0,y=0;n<=j;n ) { y =a[n][degree-1]; } if(y==x) { for(n=0,y=0;n<i;n ) { y =a[degree-1][n]; } y =k; if(y==x) { a[i 1][j]=k; b[k]=1; a[i][j]=m; b[m]=1; a[ i][ j]=h; b[h]=1; } else { continue; } } else { continue; } } else { b[a[i][j 1]]=0; a[i][j 1]=0; b[a[i][j]]=0; a[i][j]=0; if(j==1) { b[a[i 1][j-1]]=0; a[i 1][j-1]=0; j--; break; } else { continue; } } } } else { if(j==1) { //這個判斷好像無效 if(j==degree-2) { b[a[i][j 1]]=0; a[i][j 1]=0; } b[a[i][j]]=0; a[i][j]=0; j--; b[a[i 1][j]]=0; a[i 1][j]=0; break; } if(j==degree-2) { b[a[i][j]]=0; a[i][j]=0; b[a[i][j 1]]=0; a[i][j 1]=0; //某列兩個數值歸0 } continue; } } if(i==degree-1 && j==degree-1) { //已經到達第5行、第五列 for(k=0;k<degree;k ) { for(h=0;h<degree;h ) { //滿足條件的結果輸出 printf("M",a[k][h]); } printf("\n"); } printf("\n"); number ; printf("num=]\n",number); if(number==100) { getchar(); getchar(); } for(k=degree-2;k<degree;k ) { for(h=1;h<degree;h ) { b[a[k][h]]=0; a[k][h]=0; //第四行、第五行歸0 } } b[a[degree-1][0]]=0; a[degree-1][0]=0; //第五行第一列歸0 i--; j=0; break; } } } if(m>max) { //超出理論範圍 if(temp!=0) { b[temp]=0; } if(j==0 && i>0) { i--; j=degree-1; b[a[i][j]]=0; a[i][j]=0; j--; } else if(j>0) { j--; b[a[i 1][j]]=0; a[i 1][j]=0; } else if(i==0 && j==0) { break; } } } printf("the total number is %d\n",number); //結果輸出 return 0; }

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved