搭積木問題
題目描述:
小明最近喜歡搭數字積木。一共有10塊積木,每個積木上有一個數字,0~9。
搭積木規則:
每個積木放到其它兩個積木的上面,並且一定比下面的兩個積木數字小。
最後搭成4層的金字塔形,必須用完所有的積木。
下面是兩種合格的搭法:
0
1 2
3 4 5
6 7 8 9
0
3 1
7 5 2
9 8 6 4
請你計算這樣的搭法一共有多少種?
算法分析:
首先題目只說有10塊積木,對於這種小規模的數據不需要考慮太多塊積木的情況,我們就寫10塊積木的算法,簡化程序,方便快捷得到結果,符合實用性原則。該算法和全排列算法比較類似,可以參考前面的藍橋杯2020預賽題中的全排列算法,加深理解。
代碼:
import java.util.Scanner;
public class Main{
private static int N=0;
public static void main(String args[]){
int a[]= {0,1,2,3,4,5,6,7,8,9};
//0表示從0開始
f(a,0);
System.out.println(N);
}
private static void f(int[] a, int k) {
if(k==a.length-1) {
test(a);
return;
}
// TODO 自動生成的方法存根
for(int i=k;i<a.length;i++) {
{int t=a[i];a[i]=a[k];a[k]=t;}
f(a,k+1);
{int t=a[i];a[i]=a[k];a[k]=t;}
}
}
private static void test(int[] a) {
// TODO 自動生成的方法存根
if(a[1]<a[0]) return;
if(a[2]<a[0]) return;
if(a[3]<a[1]) return;
if(a[4]<a[1]) return;
if(a[4]<a[2]) return;
if(a[5]<a[2]) return;
if(a[6]<a[3]) return;
if(a[7]<a[3]) return;
if(a[7]<a[4]) return;
if(a[8]<a[4]) return;
if(a[8]<a[5]) return;
if(a[9]<a[5]) return;
show(a);
N++;
}
private static void show(int[] a) {
// TODO 自動生成的方法存根
System.out.println(" "+a[0]);
System.out.println(" "+a[1]+" "+a[2]);
System.out.println(" "+a[3]+" "+a[4]+" "+a[5]);
System.out.println(""+a[6]+" "+a[7]+" "+a[8]+" "+a[9]);
}
}
運行結果:(如果只要最後的N,則不需要調用show函數,直接輸出N即可,N爲768)