您的位置:首页 > 编程语言

幻方 C代码

2016-05-06 20:59 309 查看
幻方的解法:点击打开链接

互动百科:点击打开链接

直接上代码:

#include <stdio.h>
#define MAX_N 12	//幻方阶数

//判断矩阵arr是否是幻方
int CheckSquare(int arr[][MAX_N], int n)
{
//计算幻方和
int sum = (n*n*n + n)/2;

//检测各行各列的和是否等于幻方和
for(int i = 0; i < n; i ++){
int rowSum = 0, colSum = 0;
for(int j = 0; j < n; j ++){
rowSum += arr[i][j];
colSum += arr[j][i];
}
if(rowSum != sum || colSum != sum)
return 0;
}

//检测对角线的和是否等于幻方和
int s1 = 0, s2 = 0;
for(int i = 0; i < n; i ++){
s1 += arr[i][i];
s2 += arr[i][n - 1 - i];
}

return s1 == sum && s2 == sum;
}

//打印矩阵
void PrintSquare(int arr[][MAX_N], int n)
{
printf("S(%d) = %d\n", n, (n*n*n + n)/2);
for(int i = 0; i < n; i ++){
for(int j = 0; j < n; j ++)
printf(" %3d", arr[i][j]);
printf("\n");
}
printf(CheckSquare(arr, n) ? "Check Pass\n" : "Check Wrong\n");
printf("\n");
}

//交换矩阵arr中两个位置的值
void swap(int arr[][MAX_N], int x1, int y1, int x2, int y2)
{
arr[x1][y1] ^= arr[x2][y2] ^= arr[x1][y1] ^= arr[x2][y2];
}

//填充n阶奇幻方(斜步法,这里是右上移动,还可以右下,左上,左下)
//以 s 开始填充 arr 中以 arr[si][sj]为偏移的n阶奇幻方
void OddMagicSquare(int arr[][MAX_N], int si, int sj, int n, int s)
{
for(int x = 0; x < n; x ++)
for(int y = 0; y < n; y ++)
arr[x][y] = 0;

for(int i = 1, x = 0, y = (n - 1)/2; i <= n*n; i ++){
arr[si + x][sj + y] = s + i - 1;

if(n*n == i)
break;

//右上角或有数
if(0 == i%n)
x ++;

//向右上移动
else{
x --;
if(x == -1)
x = n - 1;

y ++;
if(y == n)
y = 0;
}
}
}

//填充n阶双偶幻方(Spring法)
void TwoEventMagicSquare(int arr[][MAX_N], int n)
{
for(int x = 0; x < n; x ++)
for(int y = 0; y < n; y ++)
arr[x][y] = x * n + y + 1;

for(int x = 0; x < n/2; x ++)
for(int y = 0; y < n; y ++)
if((y + 1 <= n/2 && 0 == (x + y)%2) || (y + 1 > n/2 && 1 == (x + y)%2))
{
swap(arr, x, y, n - 1 - x, n - 1 - y);
}
}

//填充n阶单偶幻方
void OneEventMagicSquare(int arr[][MAX_N], int n)
{
int m = (n - 2)/4, nn = (2*m + 1);

//填充 A, B, C, D
OddMagicSquare(arr, nn, 0, nn, 3*nn*nn + 1);
OddMagicSquare(arr, 0, nn, nn, 2*nn*nn + 1);
OddMagicSquare(arr, nn, nn, nn, nn*nn + 1);
OddMagicSquare(arr, 0, 0, nn, 1);

//在A阵中取左侧m列与D阵对应小格对调
for(int i = 0; i < nn; i ++)
for(int j = 0; j < m; j ++){
if(i != (nn - 1)/2)
swap(arr, i, j, nn + i, j);
}
//在A阵中间方格开始的m列与D阵对应小格对调
for(int i = (nn - 1)/2, j = i, k = 1; k <= m; j ++, k ++)
swap(arr, i, j, nn + i, j);

//在C阵中取右侧m-1列与B阵对应小格对调
for(int i = 0; i < nn; i ++)
for(int j = 0; j < m - 1; j ++)
swap(arr, i, nn + j, nn + i, nn + j);
}

int main()
{
int arr[MAX_N][MAX_N] = {0};
for(int n = 3; n <= MAX_N; n ++){
//奇数
if(n & 1)
OddMagicSquare(arr, 0, 0, n, 1);

//偶数
else{
//单偶数
if(n & 2)
OneEventMagicSquare(arr, n);

//双偶数
else
TwoEventMagicSquare(arr, n);
}
PrintSquare(arr, n);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: