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