#include<iostream>
#include<fstream>
#include<algorithm>
using namespace std;
const int MAX = 50;
int n;
bool board[MAX][MAX]; //board[i][j]记录形状为i,颜色为j的宝石是否已使用过
int a[MAX][MAX]; //存储宝石形状矩阵
int b[MAX][MAX]; //存储宝石颜色矩阵
bool ok(int r, int c, int k, bool isShap)
{
if(isShap) //考察当前列是否有相同形状的宝石
{
for(int i=1; i<r; i++)
{
if(a[i][c] == k)
return false;
}
}
else //考察当前列是否有相同颜色的宝石
{
if(board[a[r][c]][b[r][c]])
return false;
for(int i=1; i<r; i++)
{
if(b[i][c] == k)
return false;
}
}
return true;
}
long int num = 0; //不同的宝石排列方案数
//从上到下,从左到右递归搜索,即先行后列
void backtrack(int r, int c)
{
for(int i=c; i<=n; i++) //列
if(ok(r, c, a[r][i], true)) //考察当前列是否有相同形状的宝石
{
swap(a[r][c], a[r][i]);
for(int j=c; j<=n; j++)
if(ok(r, c, b[r][j], false)) //考察当前列是否有相同颜色的宝石
{
swap(b[r][c], b[r][j]);
board[ a[r][c] ][ b[r][c] ] = true;
if(c == n) //如果列考察完毕
{
if(r == n) //如果行考察完毕
num++;
else
backtrack(r+1, 1); //考察下一行
}
else
backtrack(r, c+1); //考察下一列
swap(b[r][c], b[r][j]);
board[ a[r][c] ][ b[r][c] ] = false;
}
swap(a[r][c], a[r][i]);
}
}
int main()
{
ifstream fin("排列宝石.txt");
cout << "\n输入正整数n:";
fin >> n; cout << n << endl;
int i, j;
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
board[i][j] = false;
a[i][j] = j;
b[i][j] = j;
}
}
backtrack(1, 1);
cout << "\n不同的宝石排列方案数为:" << num;
cout << endl << endl;
return 0;
}
排列宝石问题
最新推荐文章于 2021-12-16 19:26:46 发布