现有n种不同形状的宝石,每种宝石有足够多颗。欲将这些宝石排列成m行n列的一个矩阵,m n,使矩阵中每一行和每一列的宝石都没有相同形状。试设计一个算法,计算出对于给定的m和n有多少种不同的宝石排列方案。
方法一:(从左往右,从上往下,依次填写,保证上方,左方没有重复的)
import java.util.Scanner;
public class LaDingJuZhen3 {
static int[][] x;
static int m; //行
static int n; //列
static int mn;
static int count=0;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
m=input.nextInt();
n=input.nextInt();
mn=(m)*(n);
input.close();
x=new int[m][n];
Backtrack(0);
System.out.println(count);
}
public static void Backtrack(int t){
int i=t/n;
int j=t%n;
if(t>=mn){
count ++;
return;
}
for (int k = 0; k < n ; k++) {
if(isOk(i, j, k)){
x[i][j]=k;
Backtrack(t+1);
}
}
}
public static boolean isOk(int i,int j,int k){
for (int l = 0; l < i; l++) {
if(x[l][j]==k){
return false;
}
}
for (int l = 0; l < j; l++) {
if(x[i][l]==k){
return false;
}
}
return true;
}
}
方法2:每一行n个不同的数,行作为深度,求每一行的全排列,保证行列不重复
import java.util.Scanner;
public class LaDingJuZhen2 {
static int[][] x;
static int m;
static int n;
static int count=0;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
m=input.nextInt();
n=input.nextInt();
input.close();
x=new int[m+1][n+1];
for (int i = 0; i < m+1; i++) {
for (int j = 0; j < n+1; j++) {
x[i][j]=j;
}
}
Backtrack(1, 1);
System.out.println(count);
}
public static void outPut(){
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
System.out.print(x[i][j]+" ");
}
System.out.println();
}
System.out.println();
}
public static boolean ok(int s,int t){
for (int i = 1; i < s; i++) {
for (int j = 1; j <= n; j++) {
if(x[i][j]==x[s][j]) {
return false;
}
}
}
return true;
}
public static void swap(int x1,int y1,int x2,int y2){
int t;
t=x[x1][y1];
x[x1][y1]=x[x2][y2];
x[x2][y2]=t;
}
public static void Backtrack(int s,int t){ //s表示行 t表示列
if(s>m){
count++;
outPut();
return;
}
if(t>n){
if(ok(s, t)){
Backtrack(s+1, 1);
}
}
for (int i = t; i <= n; i++) {
swap(s, i, s, t);
Backtrack(s, t+1);
swap(s, i, s, t);
}
}
}
#include"iostream"
using namespace std;
int **x;
int count=0;
int s;
int t;
int m;
int n;
int no=0;
void OutPut()
{
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
cout<<x[i][j]<<ends;
cout<<endl;
}
// cout<<endl;
}
void swap(int &a,int &b)//要用引用
{
int p;
p=a;
a=b;
b=p;
}
int OK(int**x,int s,int t)
{
for(int k=1;k<s;k++)
for(int j=1;j<=n;j++)
if(x[k][j]==x[s][j]) return 0;
return 1;
}
void Backtrack(int s,int t)
{
int j;
if(s>m)
{
count++;
// no++;
// cout<<"矩阵:"<<no<<endl;
// OutPut();
return;
}
if(t>n)
{
if(OK(x,s,t))
Backtrack(s+1,1);
}
for(j=t;j<=n;j++)
{
swap(x[s][j],x[s][t]);
Backtrack(s,t+1);
swap(x[s][j],x[s][t]);
}
}
void main()
{
int i,j;
cin>>n>>m;
x=new int*[m+1];
for(i=0;i<=m;i++)
x[i]=new int[n+1];
for(i=0;i<=m;i++)
for(j=0;j<=n;j++)
x[i][j]=j;
Backtrack(1,1);
cout<<count<<endl;
}