现在的位置: 首页 > 综合 > 正文

趣味魔方阵

2013年11月17日 ⁄ 综合 ⁄ 共 3456字 ⁄ 字号 评论关闭

所谓魔方阵是指这样的方阵,它的每一行,每一列和每条对角线之和均相等。n阶魔方阵由1~n*n,n*n个自然数组成,且阶数n只能为奇数。要生成这样的方阵,看似非常玄乎,但其实它只有简单的三条规则,如下:
①自然数1总是在方阵的第一行中间一列;
②从自然数2到自然数n*n依次按下列规则摆放:每一个数摆放的行数比前一个数的行数少1,列数多1(注意循环);
③如果按上面规则确定的位置已经被占用,则摆放在此位置的下方(注意循环)。
代码如下(编译环境Visual C++ 6.0):
//MagicCube.h
#ifndef CARL_SEN_MAGICCUBE_H
#define CARL_SEN_MAGICCUBE_H
#include <iostream>
using std::ostream;
class MagicCube { 
private:
        int n;
        int** cube;
        void setCube();
public:
        MagicCube(int _n=1);
        MagicCube(const MagicCube& mc);
        MagicCube& operator=(const MagicCube& mc);
        ~MagicCube();
        int getN() const {return n;}
        friend ostream& operator<<(ostream& os, const MagicCube& mc);
};
#endif

//MagicCube.cpp
#include "MagicCube.h"
using std::invalid_argument;
using std::endl;
MagicCube::MagicCube(int _n): n(_n){
        if(n<0||n%2==0) {
                throw invalid_argument("invalid value n");
        }
        cube=new int*[n];
        for(int i=0; i<n; ++i) {
                cube[i]=new int[n];
        }
        setCube();
}
MagicCube::MagicCube(const MagicCube& mc) {
        n=mc.n;
        cube=new int*[n];
        int i, j;
        for(i=0; i<n; ++i) {
                cube[i]=new int[n];
        }
        for(i=0; i<n; ++i) {
                for(j=0; j<n; ++j) {
                        cube[i][j]=mc.cube[i][j];
                }
        }
}
MagicCube& MagicCube::operator=(const MagicCube& mc) {
        if(&mc!=this) {
                int i, j;
                for(i=0; i<n; ++i) {
                        delete[] cube[i];
                }
                delete[] cube;
                n=mc.n;
                cube=new int*[n];
                for(i=0; i<n; ++i) {
                        cube[i]=new int[n];
                }
                for(i=0; i<n; ++i) {
                        for(j=0; j<n; ++j) {
                                cube[i][j]=mc.cube[i][j];
                        }
                }
        }
        return *this;
}
MagicCube::~MagicCube() {
        for(int i=0; i<n; ++i) {
                delete[] cube[i];
        }
        delete[] cube;
}
void MagicCube::setCube() {
        int i, j;
        for(i=0; i<n; ++i) {
                for(j=0; j<n; ++j) {
                        cube[i][j]=0;
                }
        }
        //规则一:将1放在第一行中间一列
        int mid=n/2;
        cube[0][mid]=1;
        //按魔方阵的第二、三条规则处理其它自然数(2到n*n)
        int proRowNum=0, proColNum=mid;
        int curRowNum, curColNum;
        for(int num=2; num<=n*n; ++num) {
                //规则二:当前这个自然数的位置是前一自然数位置的行标减1,列标加1
                curRowNum=(proRowNum+n-1)%n;
                curColNum=(proColNum+1)%n;
                //规则三:如果计算出来的位置已被占用,则放在该位置的下方
                if(cube[curRowNum][curColNum]!=0) {
                        curRowNum=(proRowNum+1)%n;
                        curColNum=proColNum;
                }
                cube[curRowNum][curColNum]=num;
                proRowNum=curRowNum;
                proColNum=curColNum;
 }
}
ostream& operator<<(ostream& os, const MagicCube& mc) {
        int i, j;
        for(i=0; i<mc.n; ++i) {
                for(j=0; j<mc.n; ++j) {
                        os<<mc.cube[i][j]<<"/t";
                }
                if(i!=mc.n-1) {
                        os<<endl;
                }
        }
        return os;
}

//测试程序
#include <iostream>
#include "MagicCube.h"
using std::invalid_argument;
using std::cout;
using std::cerr;
using std::cin;
using std::endl;
int main() {
        int n=0;
        cout<<"MagicCube dimension 'n': (n>0 and n%2==1) ";
        cin>>n;
        try {
                MagicCube mc(n);
                cout<<"MagicCube["<<mc.getN()<<"]"<<endl;
                cout<<mc<<endl;
        }
        catch(const invalid_argument& e) {
                cerr<<e.what()<<endl;
        }
        return EXIT_SUCCESS;
}

抱歉!评论已关闭.