①打印魔方阵
问题:打印魔方阵,魔方阵又称纵横图,是指组成元素为自然数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; }