数据结构与算法之蛮力(穷举)算法

数据结构与算法之蛮力(穷举)算法

蛮力法是基于计算机运算速度快这一特性,在解决问题时采用的一种“惰性”的策略。这种策略不经过(或者说是经过很少的)思考,把问题的所有情况或所有过程交给计算机去一一尝试,从中找出问题的解。蛮力算法的应用很广。

枚举法(穷举法)是蛮力算法的一种,它对可能解的众多候选解按某种顺序逐一枚举和检验,并从中找出那些符合要求的候选解作为问题的解。

这种方法简单易行,尤其是对于一时想不出更好的解法的问题,不失为一种补救的好方法。但是,这种方法只能解决变量个数有限,而且每个变量可取值个数也很有限的情况,否则会造成“指数爆炸”,在计算机上难以实现。

用枚举法解决问题,通常可以从两个方面进行算法设计。
找出枚举范围:分析问题所涉及的各种情况。
找出约束条件:分析问题的解需要满足的条件,并用逻辑表达式表示。

寻规律问题

寻找规律数字:将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数构成1:2:3的比例,试求出所有满足条件的三个三位数。
例如:三个三位数192,384,576满足以上条件。

#include<iostream> 
using namespace std;
int main(){
	for(int j, i=123;i<327;i++)	{
		int a[10]={0};
		a[i/100]++;a[i%100/10]++;a[i%10]++;
		a[i*2/100]++;a[i*2%100/10]++;a[i*2%10]++;
		a[i*3/100]++;a[i*3%100/10]++;a[i*3%10]++;
		for(j=1;j<10;j++)
			if(a[j]!=1) break;
		if(j==10)
		  cout<<i<<"  "<<2*i<<"  "<<3*i<<endl;
	}
}

数字三角形问题

将1,2,······,9共9个数排成下列形态的三角形。
a
b c
d e
f g h i
其中:a~i分别表示1,2,······,9中的一个数字,并要求同时满足下列条件:
(1)a<f<i;
(2)b<d, g<h, c<e
(3)a+b+d+f=f+g+h+i=i+e+c+a=P
程序要求:
根据输入的边长之和P
输出所有满足上述条件的三角形的个数以及其中的一种方案。

#include<iostream> 
using namespace std;
int main()
{
	int a,b,c,d,e,f,g,h,i,P; 
    int x[10]={0};
	 cin>>P; 
	 if(3*P-45<6 || 3*P-45>24) {
	 	cout<<"0";
		 return 0; 
	 } 
	 for(a=1;a<8;a++)
	 {
	 	x[a]++;
	 	 for(f=a+1;f<9;f++)
	 	 {
	 	 	x[f]++;
	 	 	for(i=f+1;i<10;i++)
	 	 	{
	 	 		x[i]++;
	 	 		for(b=1;b<9;b++)
	 	 		{
	 	 			d=P-b-a-f;
					 if(x[b]||x[d] ||d<=b) continue;
					 x[b]++,x[d]++;
					 for(c=1;c<9;c++)
					 {
					 	e=P-a-c-i;
						 if(x[c]|| x[e]||e<=c)  continue;
						 x[c]++,x[e]++;
						 for(g=1;g<9;g++)
						 {
						 	h=P-f-g-i;
						 	if(x[g]||x[h]||h<=g) 
							 continue;
						 	cout<<a<<"  "<<b<<c<<d<<e<<f<<g<<h<<i<<endl;
						 }
						 x[c]--;
						 x[e]--;
					 } 
					x[d]--;
					x[b]--;
				} 
				x[i]--;
	 	 	}
	 	 	x[f]--;
	 	 }
	 	 x[a]--;
	 }
	return 0;
}

接水问题

学校里有一个水房,水房里一共装有 m 个龙头可供同学们打开水,每个龙头每秒钟的供水量相等,均为 1。
现在有 n 名同学准备接水,他们的初始接水顺序已经确定。将这些同学按接水顺序从 1到 n 编号,i号同学的接水量为 wi。接水开始时,1 到 m号同学各占一个水龙头,并同时打开水龙头接水。当其中某名同学 j 完成其接水量要求 wj 后,下一名排队等候接水的同学 k马上接替 j 同学的位置开始接水。这个换人的过程是瞬间完成的,且没有任何水的浪费。即j 同学第x 秒结束时完成接水, 则 k 同学第 x+1 秒立刻开始接水。 若当前接水人数 n’不足 m,则只有 n’个龙头供水,其它 m−n’个龙头关闭。
现在给出 n名同学的接水量,按照上述接水规则,问所有同学都接完水需要多少秒。

讲解:
第 1 秒,3 人接水。第 1秒结束时,1、2、3 号同学每人的已接水量为 1,3 号同学接完水,4 号同学接替 3 号同学开始接水。
第 2 秒,3 人接水。第 2 秒结束时,1、2 号同学每人的已接水量为 2,4 号同学的已接水量为 1。
第 3 秒,3 人接水。第 3 秒结束时,1、2 号同学每人的已接水量为 3,4 号同学的已接水量为 2。4号同学接完水,5 号同学接替 4 号同学开始接水。
第 4 秒,3 人接水。第 4 秒结束时,1、2 号同学每人的已接水量为 4,5 号同学的已接水量为 1。1、2、5 号同学接完水,即所有人完成接水。
总接水时间为 4 秒。

输出样式
water.in
8 4
23 71 87 32 70 93 80 76
water.out
163

#include <iostream>
using namespace std;
int main(){
	int w[10000]={0},l[100]={0};
	int n,m,i,j,k=0;
	cin>>n>>m;
	for(i=0;i<n;i++)
		cin>>w[i];
	for(int i=0;i<m;i++)
		l[i]=w[i];
	 j=m;
	for(i=1;;i++)	{
		for(int f=0;f<m;f++)		{
			l[f]--;
			if(l[f]==0 ){
			   if(j<n){
			   	l[f]=w[j];
			   	j++;
			   }
			   k++;
			}
		}
		if(k==n)
		break;
	}
	cout <<i<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值