在指定长度的棍子中找到能组成最大周长三角形的三根棍子

      在给定的一组代表棍子长度的数组中,找到三根棍子,可以构成三角形,并且该三角形是能组成的三角形中周长最大的。

      拿到这题,首先最能想到的一个方法就是三重循环的方法,把所有三根棍子的组合罗列出来,并对其中能组成三角形的周长与之前找到的最大周长比较,大于原先的最大周长,则更新最大周长。(判断构成三角形的充要条件:最长棍子的长度<其余两个棍子长度之和)

     但是简单的方法往往带来跟多的消耗,这里三重循环的时间复杂度为O(n^3),虽说能通过一些方法不去罗列重复的组合(如3,4,5和,3,5,4和4,5,3等等是一个组合),但是复杂度仍然为O(n^3)。那么可不可以找到一个更简单的方法呢,答案是可以的。

方法就是先对数组进行排序,并利用贪心算法先取得最长的一根棍子,之后的两根依次取最长的棍子,如果这样构不成三角形,那么以最长棍子最为三角形中最长的一条边是不行的,至于为什么这样,可以举个例子,在2,3,4,5,7,8,20中我们按照刚才的想法依次找到了20,8,7但是20>7+8,所以20,8,7构不成三角形,如果这时不放弃20,仍将20作为三角形中最长的边,那么在剩下的棍子中肯定找不出满足条件的两个棍子,因为7和8就是除了20以外最长的根子了,他俩都无法和20组成三角形,那么其他的两根组合肯定就不行了.

依据这种思想,我们便有了以下的解题源码:

#include<cstdio>
#include<cstdlib>
#include <algorithm>
using namespace std;
const int MAX_N=100;
int main()
{
	int n;
	bool isOk=false;
	int a[MAX_N];
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	  scanf("%d",&a[i]);
	sort(a,a+n);      //对数组指定范围进行升序排序
	for(int i=n-1;i>1;i--)
	{
		if(a[i]<a[i-1]+a[i-2])
		{
			isOk=true;
			printf("最大周长为%d=%d+%d+%d\n",a[i]+a[i-1]+a[i-2],a[i],a[i-1],a[i-2]);
			break;
		}
	} 
	if(!isOk)
	   printf("无法构成三角形\n"); 
	return 0;
}

这种方法在排序后,只有一层循环,循环的时间复杂度是O(n),但是排序函数的时间复杂度最小为(nlog2(n)),所以整体的时间复杂度为(nlog2(n)),远远小于原来的O(n^3).


PS:两本的《挑战》带着一起看,基础知识和具体的算题共同学习,感觉效果也不错~

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值