5-10 排列宝石问题
问题描述
现有n种不同形状的宝石,每种 n 颗,共 颗。同一种形状的n颗宝石分别具有n种不同的颜色 中的一种颜色。欲将这 颗宝石排列成n行n列的一个方阵,使方阵中每一行和每一列的宝石都有n种不同形状和n种不同颜色。试设计一个算法,计算出对 于给定的 n ,有多少种不同的宝石排列方案。
对于给定的 n,计算出不同的宝石排列方案数。
数据输入:
第 1 行有 1 个正整数 n,0
Java
package Chapter5HuiSuFa;
import java.util.Scanner;
public class PaiLieBaoShi {
private static int n;
private static int[][] a,b;
private static boolean[][] cc;
private static double count;
public static void main(String[] args){
Scanner input = new Scanner(System.in);
while (true){
count = 0.0;
n = input.nextInt();
a = new int[n+1][n+1];
b = new int[n+1][n+1];
cc = new boolean[n+1][n+1];
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++){
a[i][j] = j;
b[i][j] = j;
cc[i][j] = false;
}
backtrack(1,1);
System.out.println((int)count);
}
}
private static void backtrack(int r, int c){
for(int i=c; i<=n; i++)
if(ok(r,c,i,0)){
swap(a[r],c,i);
for(int j=c; j<=n; j++)
if(ok(r,c,j,1)){
swap(b[r],c,j);
cc[a[r][c]][b[r][c]] = true;
if(c == n){
if(r == n) count += 1.0;
else backtrack(r+1,1);
}else backtrack(r,c+1);
cc[a[r][c]][b[r][c]] = false;
swap(b[r],c,j);
}
swap(a[r],c,i);
}
}
private static boolean ok(int r, int c, int k, int fla){
if(fla > 0){
if(cc[a[r][c]][b[r][k]]) return false;
for(int i=1; i<r; i++)
if(b[i][c] == b[r][k])
return false;
}else
for(int i=1; i<r; i++)
if(a[i][c] == a[r][k])
return false;
return true;
}
private static void swap(int[] x, int i, int j){
int tmp = x[i];
x[i] = x[j];
x[j] = tmp;
}
}
Input & Output
1
1
4
6912
Reference
王晓东《计算机算法设计与分析》(第3版)P183