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

      在給定的一組代表棍子長度的數組中,找到三根棍子,可以構成三角形,並且該三角形是能組成的三角形中周長最大的。

      拿到這題,首先最能想到的一個方法就是三重循環的方法,把所有三根棍子的組合羅列出來,並對其中能組成三角形的周長與之前找到的最大周長比較,大於原先的最大周長,則更新最大周長。(判斷構成三角形的充要條件:最長棍子的長度<其餘兩個棍子長度之和)

     但是簡單的方法往往帶來跟多的消耗,這裏三重循環的時間複雜度爲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:兩本的《挑戰》帶着一起看,基礎知識和具體的算題共同學習,感覺效果也不錯~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章