ACM----三角形(有n根棍子,棍子i的長度為ai。)
題目:
有n根棍子,棍子i的長度為ai。想要從中選出三根棍子組成周長儘可能長的三角形。請輸出最大的周長,若無法組成三角形則輸出0。
限制條件
3 ≤ n ≤ 100
1 ≤ ai ≤ 10^6
輸入
n = 5
a = {2,3,4,5,10}
輸出
12(選擇3、4、5時)
輸入
n = 4
a = {4,5,10,20}
輸出
0(無論怎麼選都無法組成三角形)
解法:
這是《挑戰程式設計競賽(第二版)》裡的一道題,書中說了一種解法O(n³),另外,還特意說明另有一種O(nlogn)的解法,留給讀者思考。下面是兩種解法。
我們知道組成三角形的充要條件是:最長的邊小於其餘兩邊之和;不難想到,可以三重迴圈列舉所有的選擇方案,再判斷能否組成三角形,最後找出最大的周長即可。
另一種方法是先把棍子進行排序,然後只比較相鄰的三個棍子,最後選擇最大的周長。這樣只需一次迴圈即可。剛開始有點不明白這種思路,後來仔細想想就明白了,那就說說我的想法,假如棍子已經升序排序了,有a < b < c < d,如果有a + b > c且a + b > d,程式中並沒有比較a + b 和 d ,那麼是否會漏掉這種情況導致錯誤呢,不會的,因為如果a + b > d的話,那麼b + c 也一定 大於 d,而a + b 又小於 b + c,所以a + b 和 d後面的數的比較是多餘的,這樣就只需比較相鄰的三個棍子即可。下面上程式碼。
頭一種解法O(n³):
#include<stdio.h> int MAX(int a,int b) { return a > b ? a : b; } int main() { int a[10]; int i,j,k,n; scanf("%d",&n); for(i = 0; i < n; i++){ scanf("%d",&a[i]); } int ans = 0; //答案 //讓i < j < k 這樣棍子就不會被重複選取了 for(i = 0 ;i < n;i ++){ for(j = i + 1;j < n;j ++){ for(k = j + 1;k < n;k ++){ int l = a[i] + a[j] + a[k]; //周長 int max = MAX(a[i],MAX(a[j],a[k])); //找出最長的棍子 int rest = l - max; //其餘兩根棍子的長度之和 //如果可以構成三角形,則更新最大周長 if(rest > max){ ans = MAX(ans,l); } } } } printf("%d\n",ans); return 0; }
第二種解法O(nlogn):
#include<stdio.h>
int MAX(int a,int b)
{
return a > b ? a : b;
}
int main()
{
int a[10];
int i,j,t,n;
scanf("%d",&n);
for(i = 0; i < n; i++){
scanf("%d",&a[i]);
}
//氣泡排序(升序)
for(i = 0 ;i < n - 1;i ++){
for(j = 0;j < n- i -1;j ++){
if(a[j] > a[j + 1]){
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
}
}
int ans = 0; //答案
for(i = 0 ;i < n - 2;i ++){
int l = a[i] + a[i + 1] + a[i + 2]; //周長
//如果可以構成三角形,則更新最大周長
if(a[i] + a[i + 1] > a[i + 2]){
ans = MAX(ans,l);
}
}
printf("%d\n",ans);
return 0;
}
相關推薦
ACM----三角形(有n根棍子,棍子i的長度為ai。)
題目: 有n根棍子,棍子i的長度為ai。想要從中選出三根棍子組成周長儘可能長的三角形。請輸出最大的周長,若無法組成三角形則輸出0。 限制條件 3 ≤ n ≤ 100 1 ≤ ai ≤ 10^6 輸入 n = 5 a = {2,3,4,5,10}
有n跟棍子,棍子i的長度為ai。想要從中選出3跟棍子組成周長儘可能長的三角形。請輸出最大的周長,若無法輸出三角形則輸出0. //本題目是針對於陣列內棍子的長度為小到大的排列
例如: n = 5 ; a = {2,3,4,5,10} 輸出: 12 (選擇3,4,5時) #include <stdio.h> #include <stdlib.h> int main() { int n; int
有n根長度不同的木棒,隨意選取三根湊一個合法的三角形,求總拼湊方案的數量(2018騰訊軟體開發-後臺開發方向秋招補考試題第三題)
題目: 有n根長度不同的木棒,隨意選取三根湊一個合法的三角形,求總拼湊方案的數量。對於兩個方案,只要有一根木棒的長度不同,則視為不同拼湊方案。 輸入描述 第一行為正數t(0 <= t <= 10),表示測試用例數 接下來每兩行一個測試資料,第一行一個整數n
度度熊想去商場買一頂帽子,商場裏有N頂帽子,有些帽子的價格可能相同。度度熊想買一頂價格第三便宜的帽子,問第三便宜的帽子價格是多少?
length dex 相同 多少 turn this javascrip brush 便宜 var data=[10,25,50,10,20,80,30,30,40,90]; function fun(arr,index){ var min=Math.
有n級臺階,每次爬1或者2級臺階,用程序計算有多少種爬法
stat cnblogs 計算 多少 bsp span 方法 每次 spa 1.遞歸的方法: private static int Max(int i) { if (i<=2) { return i; }
面試題3:在一個長度為n的數組裏的所有數字都在0到n-1的範圍內。 數組中某些數字是重復的,但不知道有幾個數字是重復的。也不知道每個數字重復幾次。請找出數組中任意一個重復的數字。 例如,如果輸入長度為7的數組{2,3,1,0,2,5,3},那麽對應的輸出是第一個重復的數字2。
length value 如果 while 返回 sys public ret || package siweifasan_6_5; /** * @Description:在一個長度為n的數組裏的所有數字都在0到n-1的範圍內。 * 數組中某些數字是重復的,
現有n堆球,其中n是偶數,第i堆中有 ai 個球。現需要將其中 n / 2 堆中的球數全變成完 全平方數,另外的 n / 2 全不為完全平方數。
bcd dba amp com http abc 一行 增加 完全平方數 【問題描述】現有n堆球,其中n是偶數,第i堆中有 ai 個球。現需要將其中 n / 2 堆中的球數全變成完全平方數,另外的 n / 2 全不為完全平方數。你每一次操作可以選擇任意一堆增加或拿走(前提不
有n個整數,使前面各數順序向後移m個位置,最後m個數變成前面m個數。寫一函式:實現以上功能,在主函式中輸入n個數和輸出調整後的n個數。
import java.util.Scanner; public class Main { public static void main(String[] args){ Scanner sc = new Scann
有N個學生,每個學生的資料包括學號、姓名、3門課的成績,從鍵盤輸入N個學生的資料,要求打印出3門課的總平均成績,以及最高分的學生的資料(包括學號、姓名、3門課成績)
import java.util.Scanner; public class Main { public static void main(String[] args){ Scanner sc = new Sca
煤球數目 有一堆煤球,堆成三角稜錐形。具體: 第一層放1個, 第二層3個(排列成三角形), 第三層6個(排列成三角形), 第四層10個(排列成三角形), .... 如果一共有100層,共有多少個煤球?
package LQB; public class B2016Yc1 { public static void main(String[] args) { int num = 0; int sum=0; for(int i = 1;i<=100;i++){ num+=i; su
有n個整數,指定位置m處插入g個值(用指標和函式)
#include <stdio.h> void main() { void move(int *p,int *s,int n,int m,int g); int a[30],b[20]; i
LeetCode 給定一個 N 叉樹,找到其最大深度。 最大深度是指從根節點到最遠葉子節點的最長路徑上的節點總數
/* // Definition for a Node. class Node { public: int val; vector<Node*> children; Node() {}  
Problem C: 指標:有n個整數,使其前面各數順序向後移m個位置,最後m個數變成最前面m個數
#include<stdio.h> int move(int *x,int n,int m) { int t[255]; int i; //int *p;指標迴圈變數p for(i=0;i<n;i++) t[i]=x[i];
[Al]演算法:有n級階梯,每次走1步或2步,最多有多少種走法
@Filename : floor.c * @Author : Mr.Zhong * @Date : 2018-11-02 * @Description: n級階梯,每次走一步或2步,最多有多少種走法 * @Analysis :
Bellman-Ford算法——為什麽要循環V-1次?圖有n個點,又不能有回路,所以最短路徑最多n-1邊。又因為每次循環,至少relax一邊所以最多n-1次就行了!
bold source 頂點 路由 偽代碼 font 端點 -a 自底向上 單源最短路徑 給定一個圖,和一個源頂點src,找到從src到其它所有所有頂點的最短路徑,圖中可能含有負權值的邊。 Dijksra的算法是一個貪婪算法,時間復雜度是O(VLogV)(使用最小堆)。但是
一個樓梯有N個臺階,小明從臺階最底層地面上樓梯,小明一次可最大跨3階(也就是說每次邁步可以上1階,2階,或者3階)。問小明爬上頂一共有多少中步伐組合
def fun(n): if n ==0: return ‘error’ elif n 1: return 1 elif n2: return 2 else: return fun(n-1)+fun(n-2) print(fun(3)) def fun(b):
給定一個二維平面,平面上有 n 個點,求最多有多少個點在同一條直線上。
需求:給定一個二維平面,平面上有 n 個點,求最多有多少個點在同一條直線上。 分析思路: 1、將所有點二維座標化,即定義出所有點的x,y座標值 2、遍歷出所有取出兩點的情況(不考慮先後順序),根據任意兩點都確定一條直線,直線引數為k斜率,b與y軸交點的縱座標(此時x=0),將他們放入一個
ACMNO.41C語言-數字調序 有n個整數,使前面各數順序向後移m個位置,最後m個數變成前面m個數,見圖。寫一函式:實現以上功能,在主函式中輸入n個數和輸出調整後的n個數
題目描述 有n個整數,使前面各數順序向後移m個位置,最後m個數變成前面m個數,見圖。 寫一函式:實現以上功能,在主函式中輸入n個數和輸出調整後的n個數。 輸入 輸入資料的個數n n個整數 移動的位置m 輸出 移動後的n個數 樣例輸入 10 1 2 3 4
(C/C++語言實現)度度熊想去商場買一頂帽子,商場裡有N頂帽子,有些帽子的價格可能相同。度度熊想買一頂價格第三便宜的帽子,問第三便宜的帽子價格是多少?
[程式設計題] 買帽子時間限制:1秒空間限制:32768K度度熊想去商場買一頂帽子,商場裡有N頂帽子,有些帽子的價格可能相同。度度熊想買一頂價格第三便宜的帽子,問第三便宜的帽子價格是多少? 輸入描述:首先輸入一個正整數N(N <= 50),接下來輸入N個數表示每頂帽子的價格(價格均是
C++求解:平面上有n個點,問總共可以組成多少條直線
思路 對輸入的點,兩兩組合求取斜率,這樣可能會出現某一斜率對應多對點。然後對屬於同一斜率的多對點,當成一幅圖,求取連通分支個數。 這裡對對屬於同一斜率的多對點,當成一幅圖,求取連通分支個數解釋一下: 假設對於斜率k=1.0,有點對 (1,1) ,(2,2