构造一个3*3的拉丁方阵,使该矩阵中的每行每列中数字1,2,3都只出现一次。30分不成敬意。
发布网友
发布时间:2022-05-20 16:17
我来回答
共2个回答
热心网友
时间:2023-10-31 20:49
根本不止3种情况,应该有12种。
3 2 1
2 1 3
1 3 2
3 2 1
1 3 2
2 1 3
2 1 3
3 2 1
1 3 2
2 1 3
1 3 2
3 2 1
1 3 2
3 2 1
2 1 3
1 3 2
2 1 3
3 2 1
1 2 3
2 3 1
3 1 2
1 2 3
3 1 2
2 3 1
2 3 1
1 2 3
3 1 2
2 3 1
3 1 2
1 2 3
3 1 2
1 2 3
2 3 1
3 1 2
2 3 1
1 2 3
程序如下:
#include <stdio.h>
#include <string.h>
void init(int seed[3], int a[3][3])
{
int i, j;
for(i=0; i<3; i++){
for(j=0; j<3; j++){
a[i][j] = seed[(i+j)%3];
}
}
}
void print(int x[3][3])
{
int i, j;
for(i=0; i<3; i++){
for(j=0; j<3; j++){
printf("%d ", x[i][j]);
}
printf("\n");
}
}
void show(int seed[3])
{
int x[3][3];
int a[3][3];
int i, j, k;
init(seed, a);
for(i=0; i<3; i++){
for(j=0; j<3; j++){
if(j!=i){
k=3-i-j;
memcpy(x[0],a[i],sizeof(int[3]));
memcpy(x[1],a[j],sizeof(int[3]));
memcpy(x[2],a[k],sizeof(int[3]));
print(x);
printf("\n");
}
}
}
}
void main()
{
int i;
int asc[3]={1,2,3}, dsc[3]={3,2,1};
int matrix[3][3];
show(dsc);
show(asc);
}
热心网友
时间:2023-10-31 20:49
/*
来自n个部队的n种*的n×n名军官,
如果能排成一个正方形,每一行,每一列的n名军官来自不同的部队并且*各不相同,
那么就称这个方阵叫正交拉丁方阵。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
分配 rowSize * colSize 的二维数组空间
*/
int ** mallocTwoDimensionArray(int rowSize,int colSize)
{
int **array = (int**)malloc(sizeof(int*)*rowSize);
int i,j;
if(array == NULL)
{
return NULL;
}
else
{
for(i=0;i<rowSize;i++)
{
array[i] = (int*)malloc(sizeof(int)*colSize);
if(array[i] == NULL)
{
for(j=0;j<i;j++)
{
free(array[j]);
}
return NULL;
}
else
{
memset(array[i],0,colSize*sizeof(int));
}
}
return array;
}
}
struct LatinSquare
{
int size;
int **square;
LatinSquare * next;
};
/*
保存大小为 size * size 大小的拉丁方阵 square
到链表 head 中
返回:是否成功保存到链表中
*/
int saveLatinSquare(struct LatinSquare *head,int size,int** square)
{
struct LatinSquare *p;
int i,j;
p = (struct LatinSquare *)malloc(sizeof(struct LatinSquare));
if(p == NULL)
{
return 0;
}
else
{
// 拉丁矩阵大小
p->size = size;
p->square = mallocTwoDimensionArray(size,size);
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
{
p->square[i][j] = square[i][j];
}
}
// 添加构造好的拉丁矩阵到链表中
p->next = head->next;
head->next = p;
return 1;
}
}
/*
输出拉丁矩阵
*/
void printLatinSquare(struct LatinSquare *p)
{
int i,j;
if(p == NULL)
{
return ;
}
else
{
for(i=0;i<p->size;i++)
{
for(j=0;j<p->size;j++)
{
printf("%d ",p->square[i][j]);
}
printf("\n");
}
printf("\n");
}
}
/*
构造大小为 size * size 大小的拉丁方阵
构造结果通过链表 head 返回
square :当前正在构造的拉丁方阵
row :当前正在构造的拉丁方阵的行号
col :当前正在构造的拉丁方阵的列号
generatedSquareNum : 已经构造好的拉丁方阵数
返回:
能构造出的拉丁反正种数
*/
void generateLatinSquare(int size,struct LatinSquare *head,int *totalSquareNum ,int**square,int row,int col)
{
int i,j,k;
int *isNumberUsed = (int*)malloc(sizeof(int)*(size+1));
if(row == size)
{
/*
保存构造好的拉丁矩阵到结构体中。
对于构造种数比较小的拉丁矩阵适用。
构造种数比较多的,不要保存,内存会不够。
*/
saveLatinSquare(head,size,square);
/*
构造种数加一
*/
(*totalSquareNum) ++;
/*
输出构造好的拉丁矩阵到屏幕。
根据需要可以关闭这里的输出(构造种数比较少的,结果直接通过链表返回)
*/
printf("第 %d 个大小为 %d 的拉丁方阵:\n",*totalSquareNum,size);
printLatinSquare(head->next);
}
else
{
if(square == NULL)
{
square = mallocTwoDimensionArray(size,size);
}
memset(isNumberUsed,0,sizeof(int)*(size+1));
// 所在列上已经使用过的数字
for(i=0;i<row;i++)
{
isNumberUsed[square[i][col]]=1;
}
// 所在行上已经使用过的数字
for(j=0;j<col;j++)
{
isNumberUsed[square[row][j]]=1;
}
// 枚举没有被使用过的数字
for(k=1;k<=size;k++)
{
if(!isNumberUsed[k])
{
square[row][col] = k;
// 递归构造下一位上的数字
generateLatinSquare(size,head,totalSquareNum,square,row+(col+1)/size,(col+1)%size);
}
}
free(isNumberUsed);
}
}
int main(int argc, char *argv[])
{
int i,j,k;
int size,totalSquareNum;
struct LatinSquare head ,*p;
head.next = NULL;
// 构造大小从 3 ~ 10 的拉丁方阵
for(size = 3;size <=6;size ++)
{
head.next = NULL;
totalSquareNum = 0;
generateLatinSquare(size,&head,&totalSquareNum,NULL,0,0);
printf("大小为 %d 的拉丁方阵一共能构造 %d 个。\n\n",size,totalSquareNum);
/*
for(k=0,p=head.next;p!=NULL;p=p->next,k++)
{
printf("第 %d 个大小为 %d 的拉丁方阵:\n",k,size);
for(i=0;i<p->size;i++)
{
for(j=0;j<p->size;j++)
{
printf("%d ",p->square[i][j]);
}
printf("\n");
}
printf("\n");
}
*/
}
return 0;
}