蓝桥杯题目练习 提升篇 [蓝桥杯2016初赛]搭积木

搭积木

题目描述

小明最近喜欢搭数字积木,一共有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;
}
发布了128 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Ace_bb/article/details/104296875