看到敏感的GEEK字樣,果斷先讀了這題,然後演算紙上各種劃拉。。。
題意:構造反幻方(貌似就是和幻方相反的意思)。實際就是個簡單的找規律,
我的構造方法:當大於等於5階時,按左到右,上到下順序放入1到N*N
對幻方的階數分奇偶討論下
奇數:行和,列和,對角和都是相應中間數的N倍,滿足a*N(a為正整數)所以只有正中間列和行還有對角的4個相等,只需調換相應的幾個數使其不為a*N形式,且互不相等即可,由於階數大於等於5 ,可以找到相應的調換使相應的和變成a*N+1、a*N+2,a*N-1,a*N-2(3階會出現a*N1-2與a*N2+1相等的情況)。
偶數:行、列對角和都滿足4*n+2、這時只有2個對角和能相等,當階數大於4時直接把中間的4個數隨便調換2個就可以了,構造出2個4*n型的數(4階情況出現2個4*N型數相等的)。
3和4階的話直接輸出範例即可。
構造方法有很多,有在網上找到什麼公式的是蛇形排列好像也滿足。還有樸素的構造方法就是隨機產生矩陣,然後各種搜尋變換,直到滿足條件為止。
代碼有點繞直接輸出就好
#include <cstdio>#include <string.h>int ans[205][205];int I=0;void swap (int &a,int &b){ a^=b^=a^=b;}int main (){ int n,i,j; int cas; scanf("%d",&cas); while (cas--) { scanf("%d",&n); int t=0; for (i=0 ; i<n ; ++i) for (j=0 ; j<n ; ++j) { ans[i][j]=++t; } if(n==3) { ans[0][0]=7;ans[0][1]=5;ans[0][2]=2; ans[1][0]=1;ans[1][1]=4;ans[1][2]=8; ans[2][0]=3;ans[2][1]=6;ans[2][2]=9; } else if(n==4) { ans[0][0]=2;ans[0][1]=8;ans[0][2]=15;ans[0][3]=1; ans[1][0]=5;ans[1][1]=12;ans[1][2]=10;ans[1][3]=16; ans[2][0]=6;ans[2][1]=9;ans[2][2]=4;ans[2][3]=14; ans[3][0]=3;ans[3][1]=7;ans[3][2]=11;ans[3][3]=13; } else if(n&1) { swap(ans[n/2][n/2],ans[n/2][n/2+1]); swap(ans[n/2-1][n/2+1],ans[n/2-1][n/2-1]); } else { swap(ans[n/2-1][n/2-1],ans[n/2-1][n/2]); } printf("Case #%d:\n",++I); for (i=0 ; i<n ; ++i) { int sum=0; for (j=0 ; j<n ; ++j) { printf("%d ",ans[i][j]); } printf("\n"); } } return 0;}