幻方算法--模拟人工

//幻方算法--模拟人工
//实现功能:
//输入幻方的阶数,为任意正整数,即矩阵的边长,输出该阶的幻方
//如:输入4,输出
//1  2  3  4
//12 13 14 5
//11 16 15 6
//10 9  8  7
#include <stdio.h>
#include <stdlib.h>
#define NULL 0

template <class ElementType>
class CMatrix//定义矩阵类
{
public:
    int iCurrentRows;
    int iCurrentCols;
private:
    int rows;
    int cols;
    ElementType *head;//只读,存放的元素类型,双精度数组中存放矩阵中各元素,按行存放
public:
    //初始化对象
    CMatrix()
    {
        rows=0;
        cols=0;
        iCurrentRows=0;
        iCurrentCols=0;
        head=NULL;
    }
    //建立一个数组,给定行列
    void CreateMatrix(int Rows,int Cols)
    {
        rows=Rows;
        cols=Cols;
        head=new ElementType[rows*cols];//为矩阵动态分配存储
    }

    //析构函数,释放空间
    ~CMatrix()
    {
       //FreeMemory();
    }

    //设置矩阵某一点的值
    void Set(int row,int col,ElementType val)//给元素赋值,重载运算符()
    {
        if(row>=1&&rows<=rows&&col>=1&&col<=cols)
            head[(row-1)*cols+(col-1)]=val;
        else
            return;
    }

    //返回元素的值
    ElementType operator()(int row,int col)//用来返回元素的值
    {
        ElementType Zero=0;
        return (row>=1&&row<=rows&&col>=1&&col<=cols)?head[(row-1)*cols+(col-1)]:Zero;
        //在内存中是按行列顺序存放矩阵元素的,所以需要给出行列再进行换算,算出在HEA
D中的下标
    }
    int GetRows()
    {
        return rows;
    }

    int GetCols()
    {
        return cols;
    }
    void FreeMemory()
    {
        if(head!=NULL)
           delete head;//释放矩阵所占有的动态空间
        head=NULL;
    }
};
void SetOElement(int N,/*幻方阶数*/int num,/*幻方圈数序列,最外边为第一圈*/CMatri
x<int> Matrix/*幻方矩阵*/);
int GetStartValueO(int N,/*幻方阶数*/int n/*幻方圈数序列,最外边为第一圈*/);

//////////////////-------Main-----------------------//////////////
void main()
{
    char c;
    int n;//幻方阶数
    int i,j;//循环变量
    CMatrix<int> Matrix;//声明自定义矩阵类
first:    
    printf("输入幻方阶数:");
    scanf("%d",&n);
    Matrix.CreateMatrix(n,n);//建立该阶矩阵,动态分配内存
    int n1;//幻方圈数
    n1=n/2;
    //如果幻方中心有一个孤立的数据,即该圈只有一个元素,则设置该数的值
    if(n%2)
        Matrix.Set((n+1)/2,(n+1)/2,n*n);
    for(i=1;i<=n1;i++)
        //设置每一圈的元素值
        SetOElement(n,i,Matrix);
    for(i=1;i<=n;i++)//输出幻方
    {
        for(j=1;j<=n;j++)
            printf("%5d",Matrix(i,j));
        printf("\n");
    }
     Matrix.FreeMemory();//释放申请的内存空间
     printf("是否继续?(Y/N)\n");
     scanf("%c",&c);
     scanf("%c",&c);
     if(c=='Y'||c=='y')
         goto first;
     else
         exit(0);
}
///////////////////////////////////////////////////////////////////////////////
//设置幻方每一圈的值,最外面为第一圈
void SetOElement(int N,int num,CMatrix<int> Matrix)
{
    int i,j,k;//循环变量
    int StartValue;//这一圈起始的数据值
    StartValue=GetStartValueO(N,num);
    int StartI,StartJ;//这一圈起始下标
    StartI=num;
    StartJ=num;
    int n;//这一圈的阶数
    n=N-2*(num-1);
    for(k=StartValue;k<=(n-1)*4+StartValue-1;)
    {
        //分别设置上,右,下,左各条边的值
        i=StartI;
        for(j=StartJ;j<=StartJ+n-1;j++)
        {
            Matrix.Set(i,j,k);
            k++;
        }
        k--;//四个角落上的数据是重复设置的,所以K要减1
        j=StartJ+n-1;
        for(i=StartI;i<=StartI+n-1;i++)
        {
            Matrix.Set(i,j,k);
            k++;
        }
        k--;//四个角落上的数据是重复设置的,所以K要减1
        i=StartI+n-1;
        for(j=StartJ+n-1;j>=StartJ;j--)
        {
            Matrix.Set(i,j,k);
            k++;
        }
        k--;//四个角落上的数据是重复设置的,所以K要减1
        j=StartJ;
        for(i=StartI+n-1;i>=StartI+1;i--)
        {
            Matrix.Set(i,j,k);
            k++;
        }
    }
}

//获得某一圈的开始值
int GetStartValueO(int N,int n)
{
    int i;
    int Start=0;
    for(i=1;i<n;i++)//开始值
        Start+=(N-2*(i-1)-1)*4;
    return Start+1;
}



评论: 1 | 引用: 0 | 查看次数: -
回复回复未来的云[2008-02-24 02:24 AM | del]
来深了..看不懂..呵呵..
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.