程序设计竞赛系列(一)C/C++ 穷竭算法(暴搜)与二分搜索

相信很多人在大学阶段都有一个想要拿到ACM-ICPC,GCJ,TopCoder的比赛奖牌的意愿,但是市面上很多的课程参差不齐,质量没有保证而且价格也有很多贵的离谱。我希望我的文章可以帮助大家节约学习成本,并且能够提供更高质量的学习途径。本系列文章的题目都是选自一些出名的算法书籍,是没有原创题目的。但是我会用更好理解的方式,把你难以看懂的算法讲解尽量变的更加容易理解。这是我的目标,愿与大家共同学习,共同进步。

在这里插入图片描述

程序设计竞赛的大概介绍

程序设计竞赛的类型有很多,有解题的有拼性能的。可以说各种各样,我们讲的是程序设计所以主讲的内容是解题的。这类比赛呢,在开始之前参赛选手就会知道题目的数量,而他们的任务也就是在限定的时间内尽可能多的(当然正确与满足条件也是必须的)完成这些题目。

本文为程序设计竞赛系列的第一篇也是入门的文章,我们今天会介绍两种算法:穷竭算法二分搜索

穷竭算法

穷竭算法利弊分析

穷竭算法,是很多人都会用到的一种算法,它的优点是简单,但是它也有巨大的弊端。那就是它的复杂度。它的复杂度直接与它的循环次数成指数关系。假设n是一个每次循环内的次数,m为它的循环个数。那么它的复杂度为O(n^m),也就是说如果你做了四重循环那么你的复杂度就已经是一个可怕的数字。如果有五重甚至更多,基本你就要面临超时了。
当然在一些地方这个算法还是非常好用的,下面咱们就引入一个题目来对它进一步描述

题目: 三角形,经典的算法入门题目在这里插入图片描述

对于这个题目我们可以这样分析,任选三根棍子判断他们是否符合组成三角形的条件任意两边之和大于第三边,如果满足那么我们就用某种手段把它记录下来,并且当出现周长更大的三角形时,我们的算法可以自主的将周长更大的三角形的周长替换掉之前记录下来的周长。这样的话我们便能够有了大概的思路。

  1. 判断是否能组成三角形。
  2. 如果可以,就把这个三角形的周长与之前的三角形的周长进行比大小,保留大的那一个并且与下个被判断可以组成三角形的三根棍子比周长。并再次保留较长的那一个。
  3. 输出最终被保留下来的三角形。
    下面我们就用算法来表示这个过程吧。
int n, a[Max];
void solve(){
	int ans = 0;  //答案

	//让i<j<k, 这样棍子就不会被重复选中了
	for(int i = 0; i < n; i++){
		for(int j = i +1; j <n; j++){
			for(int k= j + 1; k< n ; k++){
			int  len = a[i] + a[j] + a[k];               //周长
			int ma = max(a[i] , max(a[j], a[k]));//最长棍子的长度
			int rest = len - ma;
		if(ma < rest){
		//  可以组成三角形,如果可以更新答案则更新
		ans = max(ans, len);
			 }
 		}
 	}
printf("%d\n", ans);
}

	

下面我们来讲解一下这个算法:首先我们赋值了ans如果组不成三角形的话ans的值会为0,如果可以组成三角形的话ans的值会是最大三角形的周长。 然后进入重点 我们的三重for循环有的对语法概念记得有些模糊的朋友,看到这里会觉得有点奇怪,这个算法难道不是第一次运行时 i=0, j=1,c=2,第二次运行 i=1,j=2,c=3以此类推吗。其实不是的。因为我们的for循环的先后次序是先从外循环进入内循环然后执行完内循环中的所有循环再返回外循环。所以实际上是,所有棒子的所有可能组合都涉及到了。再来解析最内层的循环中的内容。首先我们让三根棒子的长度相加赋值给len,实际上len就是周长(如果可以组成三角形的话)然后呢我们再让把三跟棍子中,最长的棍子的长度赋值给 ma,让剩下两根棍子长度之和赋值给rest,那么我们只要比较ma是否小于rest就可以判断是否能够组成三角形。如果可以的话我们就把最大的周长赋给ans,然后再继续循环直到执行完所有循环,因为这样的话后面如果有周长更长的三角形会替换掉原来的ans值并重新赋值给ans。这样我们就完成了输出最大周长的任务

讲到这里相比你对穷竭算法有了很好的了解了。

在这里插入图片描述

二分搜索

鉴于天色过晚,博主会在3.10晚上之前完成二分搜索的更新。各位晚安,好梦!

发布了8 篇原创文章 · 获赞 41 · 访问量 4682

猜你喜欢

转载自blog.csdn.net/weixin_45950372/article/details/104743305