题目描述
构造 N*N 阶的拉丁方阵(2<=N<=9),使方阵中的每一行和每一列中数字1到N只出现一次。如N=3时: 1 2 3 2 3 1 3 1 2
输入
n。
输出
输出对应的拉丁矩阵,每两个数字之间间隔一个空格,每输出n个数后换行。
样例输入
3
样例输出
1 2 3 2 3 1 3 1 2
#include<iostream>
using namespace std;
int store[20][20]={0},vs[10][10]={0},n;
int total,f=false;
bool pan1(int x)//判断行是否循环
{
int m;
for(int i=0;i<n;i++)
if(store[x][i]==1)m=i;
for(int i=0;i<n;i++)
{
if(store[x][(m+i)%n]!=i+1)
return false;
}
return true;
}
bool pan2(int y)//判断列是否循环
{
int m;
for(int i=0;i<n;i++)
if(store[i][y]==1)m=i;
for(int i=0;i<n;i++)
{
if(store[(m+i)%n][y]!=i+1)
return false;
}
return true;
}
bool judge(int x,int y,int key)
{
int temp=x,temp1=y;
for(int i=0;i<n;i++)
if(store[x][i]==key)return false;
for(int i=0;i<n;i++)
if(store[i][y]==key)return false;
return true;
}
bool judge2()//判断整个数组是否循环
{
for(int i=0;i<n;i++)
if(!pan1(i))return false;
for(int i=0;i<n;i++)
if(!pan2(i))return false;
return true;
}
void dfs(int k,int x1,int y1)
{
if(f)return;
if(k==total+1&&judge2())
{
for(int i=0;i<n;i++)
{
for(int k=0;k<n;k++)
{
cout<<store[i][k]<<" ";
}
cout<<endl;
}
f=true;
}
else
{
for(int i=1;i<=n;i++)
{
if(judge(x1,y1,i))
{
int X=x1,Y=y1;
store[x1][y1]=i;
if(y1==n-1)
{
Y=0;
X++;
}
else Y++;
dfs(k+1,X,Y);
store[x1][y1]=0;
}
}
}
}
int main()
{
cin>>n;
total=n*n;
dfs(1,0,0);
return 0;
}