首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

拉丁方阵个数统计!解决思路

2012-03-14 
拉丁方阵个数统计!今天在一篇入门题上看到了下面这个题目,看了N久都没想出答案,GOOGLE了一下,结果除了找到

拉丁方阵个数统计!
今天在一篇入门题上看到了下面这个题目,看了N久都没想出答案,GOOGLE了一下,结果除了找到一篇看不懂的之外,其余人都没做出来,所以在此向各位达人们求教。
题目如下:

在N行N列的数阵中,   数K(1〈=K〈=N)在每行和每列中出现且仅出现一次,这样的数阵叫N阶拉丁方阵。例如下图就是一个五阶拉丁方阵。编一程序,从键盘输入N值后,打印出所有不同的N阶拉丁方阵,并统计个数。

                1     2     3     4     5
                2     3     4     5     1
                3     4     5     1     2
                4     5     1     2     3
                5     1     2     3     4
请注意最后要输出所有方阵而且要统计个数。

[解决办法]
Latin squares
n L(n)
11
22
312
4576
5161280
6812851200
761479419904000
8108776032459082956800
95524751496156892842531225600
109982437658213039871725064756920320000
11776966836171770144107444346734230682311065600000
//已验证算法n=1,2,3,4,5,6时符合。超过6后int溢出,验证6时建议注释掉make函数
//中的print();否则你将无法忍受几个小时的等待
//代码引用自:http://hi.baidu.com/wxw12345/blog/item/7a7585cb0377cdfc53664f38.html
#include <stdio.h>
#include <iostream>

#define ok 1
#define no 0

int array[10][10],N,count=0,result_num=0;

bool check(int x,int y);
void make(int x,int y);
void print();

int main(){
printf( "请输入矩阵的阶数: ");
scanf( "%d ",&N);
make(0,0);
printf( "一共有%d个%d阶拉丁方阵!\n ",result_num,N);
system( "pause ");
}

bool check(int x,int y){
int i;
int checknum=array[x][y];
for( i=0;i <y;i++)
if(checknum==array[x][i]) return no;
for(i=0;i <x;i++)
if(checknum==array[i][y]) return no;
return ok;
}
void make(int x,int y){
if(count==N*N){
print();
result_num++;
}
else{
for(int i=1;i <=N;++i){
array[x][y]=i;
count++;
if(check(x,y)){
int yy=(y+1)%N;
int xx=x;
if(y==N-1) xx=x+1;
make(xx,yy);
}
--count;
}
}
}

void print(){
for(int i=0;i <N;i++){
for(int j=0;j <N;j++)
printf( "%2d ",array[i][j]);
printf( "\n ");
}
printf( "\n ");
}

热点排行