排列宝石问题 回溯算法

问题描述:

现有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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值