求一个n阶魔方阵的算法!希望能用标准c++的风格来做!
发布网友
发布时间:2022-05-10 15:11
我来回答
共2个回答
热心网友
时间:2023-10-13 00:56
#define sizem ((size / 2 - 1) / 2)
#define sizeh (size / 2)
#define sizesq (sizeh * sizeh)
void main()
{
int size = 0; //幻方大小
int x = 0, y = 0; //下一个数字所放的位置
int i, j; //循环变量
int st_i, st_x = 0, st_y = 0;
int currnum; //构造双偶数阶幻方填数的变量
int temp;
//-----输入幻方大小-------------------------------
while ((size < 1) || (size > 31) || (size == 2))
{
printf("size of magic square:");
scanf("%d", &size);
}
//-----建立二维动态数组---------------------------
int **a = new int *[size];
for (i=0; i<size; i++)
{
a[i] = new int [size];
}
if (size % 2 == 1)
{
//-----构造奇数阶(2n+1)幻方(连续摆数法)---
x = (size + 1) / 2 - 1; //第一个数字在第一行
y = 0; //的正中间位置
//-----开始填数-------------------------------
for (i=1; i<=size*size; i++)
{
a[y][x] = i;
//-----分析下一个数字的位置---------------
//-----当下一个数是size的倍数时,放在正下方
if (i % size == 0)
{
y++;
}
//-----当超出上面的边界时-----------------
else if (y == 0)
{
x++;
y = size - 1;
}
//-----当超出右面的边界时-----------------
else if (x == size - 1)
{
x = 0;
y--;
}
//-----正常情况下-------------------------
else
{
x++;
y--;
}
}
}
else if (size % 4 == 0)
{
//-----构造双偶数阶(4n)型幻方(对称法)-----
//-----第一步:分区并给分区做标记-------------
for (x=0; x<size/2; x++)
{
for (y=0; y<size/2; y++)
{
if ((x + y) % 2 == 0)
{
a[x][y] = -1;
a[x][size-y-1] = -1;
a[size-x-1][y] = -1;
a[size-x-1][size-y-1] = -1;
}
}
}
//-----第二步:填数-------------------------
for (x=0; x<size; x++)
{
for (y=0; y<size; y++)
{
currnum = x * size + y;
if (a[x][y] == -1)
{
a[x][y] = size * size - currnum;
}
else
{
a[x][y] = currnum + 1;
}
}
}
}
else
{
//-----构造单偶数阶(2(2m+1))幻方(斯特雷奇法)
//-----第一步:构造size/2阶幻方(连续摆数法)-
for (st_i=0; st_i<4; st_i++)
{
switch (st_i)
{
case 0:
st_x = 0;
st_y = 0;
break;
case 1:
st_x = sizeh;
st_y = sizeh;
break;
case 2:
st_x = sizeh;
st_y = 0;
break;
case 3:
st_x = 0;
st_y = sizeh;
break;
default:
break;
}
x = (sizeh + 1) / 2 - 1; //第一个数字在第一行
y = 0; //的正中间位置
//-----开始填数---------------------------
for (i=1; i<=sizesq; i++)
{
a[y+st_y][x+st_x] = i + sizesq * st_i;
//-----分析下一个数字的位置---------------
//-----当下一个数是size的倍数时,放在正下方
if (i % (size / 2) == 0)
{
y++;
}
//-----当超出上面的边界时-----------------
else if (y == 0)
{
x++;
y = size / 2 - 1;
}
//-----当超出右面的边界时-----------------
else if (x == size / 2 - 1)
{
x = 0;
y--;
}
//-----正常情况下-------------------------
else
{
x++;
y--;
}
}//-----end of for(i)---------------------
}//-----end of for(st_i)
//-----第二步:交换A和D的第二行起m个数字------
for (j=1; j<sizem+1; j++)
{
temp = a[(sizeh+1)/2-1][j];
a[(sizeh+1)/2-1][j] = a[(sizeh+1)/2+sizeh-1][j];
a[(sizeh+1)/2+sizeh-1][j] = temp;
}
//-----第三步:交换A和D其它行的数字-----------
for (i=0; i<sizeh; i++)
{
if (i == (sizeh + 1) / 2 - 1)
{
continue;
}
for (j=0; j<sizem; j++)
{
temp = a[i][j];
a[i][j] = a[sizeh+i][j];
a[sizeh+i][j] = temp;
}
}
//-----第四步:交换C和B最后m-1行的数字
for (i=0; i<sizeh; i++)
{
for (j=size-1; j>size-sizem; j--)
{
temp = a[i][j];
a[i][j] = a[sizeh+i][j];
a[sizeh+i][j] = temp;
}
}
}//-----end of if(size % 2 == 0)
//-----输出幻方-----------------------------------
cout<<endl;
for (i=0; i<size; i++)
{
for (j=0; j<size; j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl<<endl;
}
cout<<endl;
//-----清除数组-------------------------------
for (i=0; i<size; i++)
{
delete [] a[i];
}
delete [] a;
}
热心网友
时间:2023-10-13 00:56
图的遍历嘛!
虽然我也是刚学一学期。
可我认为,它不如数独那啊!