幻方用C语言实现(奇数阶,4k,4k+2阶)

#include<stdio.h>

//在构造4k阶幻方时候,先确定a,b,c,d的阶数,确定行列起始位置,起始数和终止数 
void MagicSquare_odd(int n,int row,int list,int start,int terminal,int a[100][100],int flag)//奇数阶幻方函数 
{
	int i=row,j=list;
	a[i][j]=start;
	for(int m=start+1;m<=terminal;m++)
	{
		i=i-1;
		j=j+1;
		if(i<row&&j>(list+(n-1)/2))//如果下一位数到了右上侧,放在前一元素下一行同一列 
		{
			i=i+2;
			j=j-1;
		}
		else
		{
			if(i<row)//特殊情况的分类 1
			{
				if(flag==3||flag==1)
				i=n;
				else if(flag==4||flag==2) 
				i=2*n;
			}
			if(j>(list+(n-1)/2))//特殊情况的分类 2
			{
				if(flag==3||flag==2)
				j=n+1;
				else if(flag==1||flag==4)
				j=1;
			}
		} 
			if(a[i][j]==0)
			{
				a[i][j]=m;
			}
			else//前一个数的后面 
			{
				i=i+2;
				j=j-1;
				a[i][j]=m;
			}
	}
}
int MagicSquare_4k(int n)//4k阶幻方的构造法 
{
	int a[100][100],b[100][100];//给定2个数组,一个逆序,一个正序。 
	int m=1;
	int i,j;
	int k=n/4;
	for(i=1;i<=n;i++)//正序分配每个数 
	{
		for(j=1;j<=n;j++)
		{
		a[i][j]=m;
		m++;
		}
	}
	m=m-1;
	for(i=1;i<=n;i++)//逆序分配每个数 
	{
		for(j=1;j<=n;j++)
		{
		b[i][j]=m;
		m--;
		}
	}
	for(i=k+1;i<=n-k;i++)
	{
		for(j=k+1;j<=n-k;j++)
		{
			b[i][j]=a[i][j];//中间正方形的数交换 
		}
	}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
		{
			if((i<=k&&j<=k)||(i<=k&&j>=n-k+1)||(i>=n-k+1&&j<=k)||(i>=n-k+1&&j>=n-k+1))//四边四个正方形交换 
			{
				b[i][j]=a[i][j];
			}
		}
	}
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
		{
		printf("%d	",b[i][j]);//打印幻方 
		}
		printf("\n");
	}
} 
int MagicSquare_4k2(int n)//4k+2阶幻方构造法 
{
	int n_1=n/2,n_2,n_3,n_4,m;
	int a[100][100]={0};
	n_2=n*n;
	n_3=n_2/4;
	m=n_1*n_1;
	n_4=(n_1+(n_1+1)/2);
	MagicSquare_odd(n_1,1,(n_1+1)/2,1,m,a,1);//A部分的幻方 
	MagicSquare_odd(n_1,n_1+1,n_4,m+1,2*m,a,2);//B部分的幻方
	MagicSquare_odd(n_1,1,n_4,2*m+1,3*m,a,3);//C部分的幻方
	MagicSquare_odd(n_1,n_1+1,(n_1+1)/2,3*m+1,n_2,a,4);//D部分的幻方
	
	int k=n/4,i,j;
	int k2=k-1;
	int temp;
	
	if(k2>0)//交换B,C后k-1列 
	{
		for(i=n;i>n-k2;i--)
			for(j=1;j<=n/2;j++)
			{
				temp=a[j][i];
				a[j][i]=a[n_1+j][i];
				a[j+n_1][i]=temp;
			}
	}
	for(i=k;i>0;i--)//交换前面k列 
	{
		
		for(j=1;j<=n/2;j++)
			{
				if(j==((n_1+1)/2))
					{
						temp=a[j][i+1];
					a[j][i+1]=a[n_1+j][i+1];
					a[j+n_1][i+1]=temp;
					}
					
				else
				{
					temp=a[j][i];
					a[j][i]=a[n_1+j][i];
					a[j+n_1][i]=temp;
				}
			}
	} 
	for(i=1;i<=n;i++)//打印这个幻方 
	{
		for(int j=1;j<=n;j++)
		{
			printf("%d	",a[i][j]);
		}
		printf("\n");
	}
	
}
void print(int a[100][100],int n)//打印幻方函数 
{
	for( int i=1;i<=n;i++)
		{
		for( int j=1;j<=n;j++)
		printf("%d	",a[i][j]);
		printf("\n");
		}
}
int main()
{
	
	int n,a[100][100]={0};
	while (scanf("%d",&n)!=EOF)
	{
			if(n%2!=0&&n>=3)
			
			{
				MagicSquare_odd(n,1,(n+1)/2,1,n*n,a,1);//奇数阶幻方函数 
				print(a,n);
			}
	else if(n>=3)
	{
		if(n%4==0)
			MagicSquare_4k(n);
			
		else
		{
			MagicSquare_4k2(n);
		}
	}
	else
	{
		printf("该数没有幻方。\n");
	}
	}
	return 0;
}

在这里插入图片描述

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值