矩阵算法总结

①打印魔方阵

问题:打印魔方阵,魔方阵又称纵横图,是指组成元素为自然数1,2,。。。n2的n*n的方阵,其中每个元素都不一样,且每行,每列以及主对角线,副对角线上元素之和都相等。

分析:构造魔方阵的方法如下:

(1)将1放到第一行中间一列(n是奇数)

(2)从2开始直到n*n为止各数依次按下列规则存放,每一个数存放的行比前一数的行数减1,列数加1.

(3)如果上一个数的行数为1,则下一个数的行数为n。

(4)当上一数的列数位n时,下一个数的列数应是1,行数减去1.

(5)如果按照上面规则确定的位置上已有数,或上一个数是第1行第n列时,则把下一个数放在上一个数的下面。

#include<stdio.h>
#define N 20
int main()
{
	int a[N][N]={0},n,i,j,k;

	while(1)	//输入矩阵的阶 
	{
		printf("请输入一个正整数n(n<=20,n是奇数):");
		scanf("%d",&n);
		if(n!=0&&n<=20&&n%2!=0)
		{
			printf("%d阶魔方矩阵.\n",n);
			break;
		}
	} 
	
	i=0;  //构建魔方阵 
	j=n/2;
	a[i][j]=1;//1放在第一行中间 
	k=2;
	while(k<=n*n)//填满为止 
	{
		i--;//行号减一
		j++;//列号增一
		if(i<0&&j>n-1)//如果上一个数是第1行第n列时,则把下一个数放在上一个数的下面	              
		{
			i=i+2;
			j=j-1;
		} 
		else
		{
			if(i<0)
			 i=n-1;
			if(j>n-1)
			 j=0;
		}
		if(a[i][j]==0)//当前的数保存到数组中
		{
			a[i][j]=k; 
		} 
		else //如果已经有数存在,则放到上一个数的下面 
		{
			i=i+2;
			j=j-1;
			a[i][j]=k;
		}
		k++; 
	} 
	for(i=0;i<n;i++)//输出魔方阵 
	{
		for(j=0;j<n;j++)
		{
			printf("%4d",a[i][j]);
		}
		printf("\n");
	}
	return 0;
}

 

②打印拉丁方阵

问题:打印拉丁方阵,N*N的拉丁方阵的每一行,每一列均为自然数1,2,。。N的全排列。且每一行,每一列均无重复数字。

分析:生成拉丁方阵的方法如下:

(1)第一行元素用随机数产生,从1开始,依次将自然数1~N填充到第一行,填入的列号由随机数产生。

(2)以第一行作为方阵的索引,即如果第一行的第i个元素值为j,则a[0][j]在各行中的列号是在第一行中从位置i开始读到的N个自然数。

#include<stdio.h>
#include<stdlib.h>
#define N 20
void Latin_Square(int n,int a[][N])
{
	int i,j,sub,index;
	for(i=1;i<=n;i++)  
	{
		do
		{
		  index=rand()%n;	
		}while(a[0][index]!=0);
		a[0][index]=i;
	}
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			if(a[0][j]=i+1)
			{
				break;
			}
		}
		sub=j+1;
		for(j=1;j<n;j++)
		{
			a[j][a[0][(sub++)%n]-1]=a[0][i];
		}
	}
}
int main()
{
	int i,j,n;
	int latin[N][N]={0};
	printf("请输入矩阵的阶n=");
	scanf("%d",&n);
	Latin_Square(n,latin);
    for(i=0;i<n;i++)
    {
    	for(j=0;j<n;j++)
    	{
    		printf("%4d",latin[i][j]);
    	}
    	printf("\n");
    }
	return 0;
}


 

转载于:https://my.oschina.net/lin546/blog/1538832

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值