搭积木
题目描述
小明最近喜欢搭数字积木,一共有10块积木,每个积木上有一个数字,0~9。
搭积木规则:每个积木放到其它两个积木的上面,并且一定比下面的两个积木数字小。
最后搭成4层的金字塔形,必须用完所有的积木
下面是两种合格的搭法:
0
1 2
3 4 5
6 7 8 9
0
3 1
7 5 2
9 8 6 4
请你计算这样的搭法一共有多少种?
输出
一个整数表示答案
解法
方法一 多层嵌套for循环
用10个for循环暴力搜索解决,看似可能会超时,但是只要保证每次循环的数都不重复,并且满足上一层的数大于下一层的数,就可以解决。
#include <iostream>
using namespace std;
int main(){
int x1,x2,x3,x4,x5;
int y1,y2,y3,y4,y5;
int a=0,b,c;
int flag[11];
for(int i=0;i<11;i++)
flag[i]=0;
for( x1=0;x1<10;x1++){
flag[x1]=1;
for(x2=0;x2<10;x2++){
if(x2<x1) continue;
if(flag[x2]==1) continue;
else flag[x2]=1;
for( x3=0;x3<10;x3++){
if(x3<x1) continue;
if(flag[x3]==1) continue;
else flag[x3]=1;
for(x4=0;x4<10;x4++){
if(x4<x2) continue;
if(flag[x4]==1) continue;
else flag[x4]=1;
for(x5=0;x5<10;x5++){
if(x5<x2 || x5<x3) continue;
if(flag[x5]==1) continue;
else flag[x5]=1;
for(y1=0;y1<10;y1++){
if(y1<x3) continue;
if(flag[y1]==1) continue;
else flag[y1]=1;
for(y2=0;y2<10;y2++){
if(y2<x4) continue;
if(flag[y2]==1) continue;
else flag[y2]=1;
for(y3=0;y3<10;y3++){
if(y3<x4 || y3<x5) continue;
if(flag[y3]==1) continue;
else flag[y3]=1;
for(y4=0;y4<10;y4++){
if(y4<x5 || y4<y1) continue;
if(flag[y4]==1) continue;
else flag[y4]=1;
for(y5=0;y5<10;y5++){
if(y5<y1) continue;
if(flag[y5]==1) continue;
else flag[y5]=1;
cout<<x1<<' '<<x2<<' '<<x3<<' '<<x4<<' '<<x5<<' '
<<y1<<' '<<y2<<' '<<y3<<' '<<y4<<' '<<y5<<endl;
a++;
flag[y5]=0;
}
flag[y4]=0;
}
flag[y3]=0;
}
flag[y2]=0;
}
flag[y1]=0;
}
flag[x5]=0;
}
flag[x4]=0;
}
flag[x3]=0;
}
flag[x2]=0;
}
flag[x1]=0;
}
cout<<a;
return 0;
}
答案是768.
这个方法有点万能,只要是这个10个数以下排列算情况总数的,基本都可以用,但要对条件进行修改。
方法二 dfs搜索
#include <iostream>
using namespace std;
int num[11];
int ans[11];
bool vis[11];
int sum;
int dfs(int index){
if(index==3){
if(num[2]<num[1]){
return 0;
}
}
if(index==4){
if(num[3]<num[1]){
return 0;
}
}
if(index==5){
if(num[4]<num[2]){
return 0;
}
}
if(index==6){
if(num[5]<num[2] || num[5]<num[3]){
return 0;
}
}
if(index==7){
if(num[6]<num[3]){
return 0;
}
}
if(index==8){
if(num[7]<num[4] ){
return 0;
}
}
if(index==9){
if(num[8]<num[4] || num[8]<num[5]){
return 0;
}
}
if(index==10){
if(num[9]<num[5] || num[9]<num[6]){
return 0;
}
}
if(index==11){
if(num[10]<num[6] ){
return 0;
}
for(int i=1;i<11;i++)
cout<<num[i]<<' ';
cout<<endl;
sum++;
}
for(int i=0;i<10;i++){
if(!vis[i]){
vis[i]=true;
num[index]=i;
dfs(index+1);
vis[i]=false;
}
}
}
int main(){
sum=0;
for(int i=0;i<11;i++){
vis[i]=false;
num[i]=-1;
}
vis[0]=true;
num[1]=0;
dfs(2);
cout<<sum;
return 0;
}