NOIP2015 D1T1 神奇的幻方
很简单的模拟题……每枚举一个点只要保存上一个点的x,y值即可,不用开数组存放
另外题目中对于K的操作都在K-1的九宫格范围内,所以我们巧妙运用++和--就可以做到每个分支一行代码
还有一点,题目中第4点说“若(K-1)既不在第一行也不在最后一列”,这个条件不必判断,因为从1~n^n每个数一定都在幻方中出现过一次,每个K一定会放到幻方中,所以第4点的条件一定会满足(虽然我不会证)
代码如下:
1 #include<cstdio> 2 using namespace std; 3 #define re register int 4 int h[40][40];//存储幻方 5 int main() 6 { 7 re n; 8 scanf("%d",&n); 9 re x=1,y=n/2+1;//存储上一个点的位置 10 h[1][n/2+1]=1; 11 re tot=1;//数字标记 12 while(tot<n*n) 13 { 14 if(x==1&&y!=n) 15 h[x=n][++y]=++tot; 16 else if(x!=1&&y==n) 17 h[--x][y=1]=++tot; 18 else if(x==1&&y==n) 19 h[++x][y]=++tot; 20 else if(!h[x-1][y+1]) 21 h[--x][++y]=++tot; 22 else 23 h[++x][y]=++tot; 24 } 25 for(re i=1;i<=n;i++) 26 { 27 for(re j=1;j<=n;j++) 28 printf("%d ",h[i][j]); 29 printf("\n"); 30 } 31 return 0; 32 }