我试图创建一个简单的3x3魔方。 3x3魔术方块由连续的整数组成(从1开始,以9开头)放入' n'按行' n'列使所有行,所有列和两个对角线总和相同。
我的算法是1上,1左。
我的问题是,我很难弄清楚为什么我不能保留我以前的号码,如果下一列被一个数字占用,则下降1。提前谢谢你
#include <iostream>
using namespace std;
int main ()
{
int magicsq[3][3];
int i,j,x;
int row=0; //start positon of row
int col=3/2; // and colum
for( i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
magicsq[i][j] = 0; //initialize to 0 your matrix
}
}
magicsq[row][col] = 1; //position to star the counting
for(x=2;x<3*3;x++)
{
row--;
col--;
if(row<0){
row=row+3;
}
if(col<0){
col=col+3;
}
if(magicsq[row][col]!=0)
{
row++; //i think this is where im having trouble
}
magicsq[row][col] = x;
}
for( i = 0; i<3;i++){
for(j = 0; j<3;j++)
{
cout<<magicsq[i][j] <<" ";
}
cout<<endl;
}
}
答案 0 :(得分:2)
按整数问题划分;这就是全部。 3/2是1。
if(magicsq[row][col!=0])
也有效(所选列将为0或1),但我认为您的意思是if(!magicsq[row][col])
答案 1 :(得分:0)
我以前从未听说过Magic Squares,并就Wikipedia咨询了他们。正如所料,我找到了various algorithms的描述。
我认为delaLoubère的算法是OP显然试图实现的算法。恕我直言,这次尝试实际上并没有那么糟糕。
我给出的提示(缺少行环绕)if(magicsq[row][col]!=0) row++;
和(缺少迭代步骤)for (x=2;x<3*3;x++)
似乎是合理的。
考虑到这一点,我运行了算法。我的第一个结果看起来并不坏,但结果检查表明它实际上是错误的。我改变了行和列计数的某些方向,但没有运气。然后,我再次访问了上面链接的文章,并将描述的内容与我实施的内容进行了比较。最后,我发现我在实现中犯了另一个语义错误。我相信OP也做到了:
该方法规定从第一行的中心列开始,编号为1.此后,填充正方形的基本运动是对角线向上和向右,一次一步。如果遇到填充的方块,则垂直向下移动一个方格而不是,然后继续像以前一样。当“向上和向右”移动将离开正方形时,它将分别缠绕到最后一行或第一列。
强调而不是由我完成 - 我错过的细节。因此,需要进行更改:如果已填充单元格,则必须丢弃新单元格的坐标。使用resp,新坐标而不是向下一行(即++row
)。环绕式。修好后,样本计算出正确的结果:
#include <iostream>
int main()
{
int magicsq[3][3] = {0}; // initializes magic square with all 0s
// Algorithm of de la Loubere:
int row = 0, col = 1; // start coordinates
// assign start cell
magicsq[row][col] = 1;
for (int x = 2; x <= 9; ++x) {
// compute up-right coordinates
int rowT = row - 1; if (rowT < 0) rowT += 3;
int colT = col + 1; if (colT >= 3) colT -= 3;
// check whether cell not yet assigned
if (magicsq[rowT][colT]) {
// compute down coordinates
if (++row >= 3) row -= 3;
} else {
// use up-right coordinates
row = rowT; col = colT;
}
// assign next cell
magicsq[row][col] = x;
}
// output of result:
std::cout << "Magic Square:" << std::endl;
for (row = 0; row < 3; ++row) {
for (col = 0; col < 3; ++col) {
std::cout << ' ' << magicsq[row][col];
}
std::cout << std::endl;
}
// check result:
std::cout << "Row sums:";
for (row = 0; row < 3; ++row) {
int sum = 0;
for (col = 0; col < 3; ++col) sum += magicsq[row][col];
std::cout << ' ' << sum;
}
std::cout << std::endl;
std::cout << "Column sums:";
for (col = 0; col < 3; ++col) {
int sum = 0;
for (row = 0; row < 3; ++row) sum += magicsq[row][col];
std::cout << ' ' << sum;
}
std::cout << std::endl;
std::cout << "Diagonal sums: ";
int sumM = 0, sumC = 0;
for (row = 0; row < 3; ++row) {
sumM += magicsq[row][row];
sumC += magicsq[row][2 - row];
}
std::cout << ' ' << sumM << ' ' << sumC << std::endl;
// done
return 0;
}
输出结果为:
Magic Square:
8 1 6
3 5 7
4 9 2
Row sums: 15 15 15
Column sums: 15 15 15
Diagonal sums: 15 15
注意:
从描述中实现这样的算法,您很容易被困。根据插图,描述使用“向上排”,“向下排”。因此,需要一个清晰的映射来定义关于矩阵存储的“向上”和“向下”意味着什么。在我的例子中,“row up”是row
递减,“row down”是row
递增。在这种特殊情况下,它可能也可以反过来,因为链接文章提到结果矩阵可以水平和垂直镜像。