1. 幻方矩阵
幻方是一种很有意思的数字矩阵,在很早著名的九宫八卦阵就与幻方有关。
幻方的定义为:
1 到 N*N 的整数填入N*N的方格中,每行和每列以及对角线的数字之和必须是相等的。
你作为八卦公司的顶级程序员,现在需要你解决一个问题,将任意奇数阶的幻方找出来。
输入:
输入包括多个测试集,每行为一个正奇数N(1<= N < 1000),0作为输入的结束且不需要处理。
输出:
对于输入的每一个N, 输出一个它所对应的N阶幻方,如果存在多个,任意一个即可。
每个幻方为N*N的矩阵,
对于每个幻方,每行输出幻方的一行,每行中的数字之间用一个或多个空格分开。不同的幻方之间用一个空行分开。
该题也采用了三种方法实现。
主界面:
Merzirac法生成奇阶幻方
算法思想:
在第一行居中的方格内放1,依次向右上方填入2、3、4…,如果右上方已有数字,则向下移一格继续填写。
输入1:产生一个5*5魔方,此魔方是固定的。可以改变宏定义中的N产生任意奇数阶魔方。
loubere法生成奇阶幻方。
算法思想:
在居中的方格向上一格内放1,依次向右上方填入2、3、4…,如果右上方已有数字,则向上移二格继续填写
输入2:产生一个5*5魔方,此魔方是固定的。可以改变宏定义中的N产生任意奇数阶魔方。
horse法生成奇阶幻方。
算法思想:
先在任意一格内放入1。向左走1步,并下走2步放入2(称为马步),向左走1步,并下走2步放入3,依次类推放到n。在n的下方放入n+1(称为跳步),再按上述方法放置到2n,在2n的下边放入2n+1。
输入3:提示,输入一个数据,此时输入的数据表示随机产生多少个不同的奇幻方,同时也可以改变宏定义中的N产生奇幻方。
输入0:任意键退出。
附件:
#include<stdio.h>
#include<windows.h>
#include <time.h>
void Merziracmagic();
void MagicHorseRandom();//随机化方法
void louberemagic();
int num(int number); //MagicHorseRandom()随机化方法产生的幻方个数
int menu_select() ;
#define N 5 //幻方必为奇数
int menu_select()
{
char c;
//system("cls");/*运行前清屏*/
printf("\t\t**** 魔方 Author byYongLiu ****\n");
printf("\t\t 1. Merziracmagic魔方 |\n");
printf("\t\t 2. louberemagic魔方|\n");
printf("\t\t 3. MagicHorseRandom魔方|\n");
printf("\t\t 0. 退出 |\n");
printf("\t\t*****************************************\n");
printf("\t\t\t请选择(0-3):");
do{
c=getchar(); /*读入选择*/
}while(c<'0'||c>'3');
return(c-'0'); /*返回选择*/
}
int main()
{
int number;
for(;;)
{
switch(menu_select())/*选择判断*/
{
case 1:
printf("\t\t1. Merziracmagic魔方 |\n");
Merziracmagic();
break;
case 2:
printf("\t\t2. louberemagic魔方|\n");
louberemagic();
break;
case 3:
printf("\t\t3. MagicHorseRandom魔方|\n");
printf("\t\tpleaseinput the number of magic ");
scanf("%d",&number);
num(number);//随机化方法
printf("\t\t\t");
break;
case 0:
printf("\t\t\t结束退出!\n"); /*结束程序*/
printf("\t\t\t");
system("pause");
exit(0);
}
}
}
int num(int number)
{
inti=0;
intcount=0;
srand((int)time(NULL));
while(++count<=number)
{
printf("\t\t%d.\n",++i);
MagicHorseRandom();
}
return1;
}
void MagicHorseRandom()
{
inta[N+1][N+1]={0};//对其初始化
inti=rand()%N+1; //ij随机在1到N*N中选取
intj=rand()%N+1;
//printf("%2d\n",i);
//printf("%2d\n",j);
a[i][j]=1;
for(intk=2;k<=N*N;k++)
{
int row=i;
int col=j;
++j; //向右走一步
if(j>N)
j=1;
++i; //向下走一步
if(i>N)
i=1;
++i; //向下走一步
if(i>N)
i=1;
if(a[i][j]==0) //如果右上方没有元素填写进去
a[i][j]=k;
else
{
i=row; //记住下标
j=col;
i++;
if(i>N)
i=1;
a[i][j]=k;
}
}
for(i=1;i<=N;i++)
{
printf("\t\t");
for(j=1;j<=N;j++)
{
printf(" %3d",a[i][j]);
}
printf("\n");
}
printf("\n");
printf("\n");
}
//Merzirac法生成奇阶幻方
//在第一行居中的方格内放1,依次向右上方填入2、3、4…,如果右上方已有数字,则向下移一格继续填写。
void Merziracmagic()
{
inta[N+1][N+1]={0};//对其初始化
inti=1,j=(N+1)/2;
a[i][j]=1; //第一行中间元素置为1
for(intk=2;k<=N*N;k++)
{
int row=i;
int col=j;
--i;
++j; //连续填写右上方元素
if(i==0)
i=N;
if(j>N)
j=1;
if(a[i][j]==0) //如果右上方没有元素填写进去
a[i][j]=k;
else
{
i=row; //记住下标
j=col;
i++;
if(i>N)
i=1;
a[i][j]=k;
}
}
for(i=1;i<=N;i++)
{
printf("\t\t");
for(j=1;j<=N;j++)
{
printf(" %3d",a[i][j]);
}
printf("\n");
}
printf("\n");
printf("\n");
}
//loubere法生成奇阶幻方
//在居中的方格向上一格内放1,依次向右上方填入2、3、4…,如果右上方已有数字,则向上移二格继续填写。
void louberemagic()
{
inta[N+1][N+1]={0};//对其初始化
inti=(N+1)/2-1,j=(N+1)/2;
a[i][j]=1; //最中间元素的上一层
for(intk=2;k<=N*N;k++)
{
int row=i;
int col=j;
--i;
++j; //连续填写右上方元素
if(i==0)
i=N;
if(j>N)
j=1;
if(a[i][j]==0) //如果右上方没有元素填写进去
a[i][j]=k;
else
{
i=row; //如果采用回溯的方法考虑的问题比较多,还是记住下标
j=col;
i--;
if(i==0)
i=N;
i--;
if(i==0)
i=N;
a[i][j]=k;
}
}
for(i=1;i<=N;i++)
{
printf("\t\t");
for(j=1;j<=N;j++)
{
printf(" %3d",a[i][j]);
}
printf("\n");
}
printf("\n");
printf("\n");
}
注:代码上传在http://download.csdn.net/detail/liuyongvs2009/7077279