问题描述:
现有n种不同形状的宝石,每种n颗,共n*n颗。同一种形状的n颗宝石分别具有n种不同的颜色c1,c2,…,cn中的一种颜色。欲将这n*n颗宝石排列成n行n列的一个方阵,使方阵中每一行和每一列的宝石都有n种不同形状和n种不同颜色。
试设计一个算法,计算出对于给定的n,有多少种不同的宝石排列方案。
输入n,输出方案数。
算法设计: 在每个位置试放置每个宝石,放满后count+1。
函数dfs中 i 表示样式,j 表示颜色,
设二维数组 visit 数组,为 1 表示该类型宝石已被放置。
row color 数组 状压记录各行已有颜色,
col color 数组 状压记录各列已有颜色,
row style 数组 状压记录各行已有样式,
col style 数组 状压记录各列已有样式。
算法复杂度O(n!)。
#include <iostream>
#define N 15
using namespace std;
int vis[N][N];
int rcol[N];
int ccol[N];
int rsty[N];
int csty[N];
int n,cnt;
void dfs(int x,int y)
{
if(x==n-1&&y==n)
{
cnt++;
return;
}
if(y==n)
{
y=0;
x++;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(vis[i][j]) continue;
if(rsty[x]&(1<<i)) continue;
if(csty[y]&(1<<i)) continue;
if(rcol[x]&(1<<j)) continue;
if(ccol[y]&(1<<j)) continue;
vis[i][j]=1;
rsty[x]^=1<<i;
csty[y]^=1<<i;
rcol[x]^=1<<j;
ccol[y]^=1<<j;
dfs(x,y+1);
rsty[x]^=1<<i;
csty[y]^=1<<i;
rcol[x]^=1<<j;
ccol[y]^=1<<j;
vis[i][j]=0;
}
}
}
int main()
{
cin>>n;
dfs(0,0);
cout<<cnt<<endl;
return 0;
}