魔方阵

群里的朋友问了这道题,刚开始想到的最笨了:枚举,然后就是判断,要是n过大了就。。。。

后来参考百度百科给出的分类考虑的方法,尝试了一下,感觉按照方法来一点也不复杂了。。

不过百度百科也提到了一种通用的方法,没有尝试。

#include<stdio.h>

# define MAXN 100

int a[MAXN][MAXN];

void swap(int *x, int *y)
{
int tmp;
tmp = *x;
*x = *y;
*y = tmp;
}

void print_odd(int n)
{
int i, j, t;
i = 1;
j = (n+1)/2;
for (t = 1; t <= n*n; ++t)
{
a[i][j] = t;
if (t%n == 0) ++i;
else
{
if ((--i) == 0) i = n;
if ((++j) == (n+1)) j = 1;
}
}
}

void print_even4(int n)
{
int i, j, p, q, t, tmp, c;
t = 0;
for (i = 1; i <= n; ++i)
for (j = 1; j <= n; ++j)
a[j][i] = ++t;
c = n/4;
for (p = 1; p <= c; ++p)
for (q = 1; q <= c; ++q)
{
i = p*4 - 3;
j = q*4 - 3;
swap(&a[i][j], &a[i+3][j+3]);
swap(&a[i+1][j+1], &a[i+2][j+2]);
swap(&a[i+3][j], &a[i][j+3]);
swap(&a[i+2][j+1], &a[i+1][j+2]);
}
}

void print_even2(int n)
{
int i, j, c, u, m;
c = n/2;
u = c*c;
print_odd(c);
for (i = 1; i <= c; ++i)
for (j = 1; j <= c; ++j)
{
a[i+c][j+c] = a[i][j]+u;
a[i+c][j] = a[i][j]+3*u;
a[i][j+c] = a[i][j]+2*u;
}
m = (c-1)/2;
for (i = 1; i <= c; ++i)
for (j = n-m+1; j <= n; ++j)
{
swap(&a[i][j], &a[i+c][j]);
if (i != m+1) swap(&a[i][j-n+m], &a[i+c][j-n+m]);
else swap(&a[i][j-n+m+m-1], &a[i+c][j-n+m+m-1]);
}
}

int main()
{
int i, j, t, n;
while (~scanf("%d", &n))
{
if (n%2 == 1) print_odd(n);
else if (n%4 == 0) print_even4(n);
else print_even2(n);
for (i = 1; i <= n; ++i)
{
for (j = 1; j <=n; ++j)
printf("%4d ", a[i][j]);
printf("\n");
}
}
return 0;
}



原文地址:https://www.cnblogs.com/JMDWQ/p/2373840.html