5th 【基础题】组合三角形

来源:互联网 发布:如何看待网络言论作文 编辑:程序博客网 时间:2024/06/11 06:02

                                         组合三角形

【题目描述】:

桌面上凌乱地摆放着N个木棍,长度分别为{a1,a2…,ai,…an},N<=6000,1<=ai<=100,000,000,选择三个木棍为边组成三角形,问有多少种不同的组合。三个木棍的不同排列,只能算一种组合。假设ai<=ajak。

【输入描述】:

第一行,一个整数N。

第二行N个木棍的长度。

【输出描述】:

只有一个数表示能够组成三角形的组数,最后的结果可能比较大。

【样例输入】

73 5 7 4 9 5 1

【样例输出】

15

【数据范围及描述】:


    难得遇到这种简单点的题目了, 虽然简单我还是要写博客的-。- 
         
   n=6000,n三次暴力肯定是不行滴,所以先排个序咯,看看有什么规律
    
        样例 1 3 4 5 5 7 9

     我们发现排完序后只要【a[i]+a[j]>a[k]】 (0<i<j<k<n+1)就满足形成三角形。
     
           所以我们穷举i和j,k从j+1开始: while(a[i]+a[j]>a[k]&&k<=n)  k++; 
      如果存在一个k恰好使得不满足上述条件了,那么说明前面的都满足,所以加上j-i-1个解。
      当j在增加的时候,无需每个j都修改k,k的值可以在原来的基础上增加,因为i是不变的,j往后推,k也必须往后推


       这样就解决问题了

中心程序:
for(int i=1;i<=n-2;i++)
        {   int k=i+2; 
            for(int j=i+1;j<=n-1;j++)
           {    
                while(a[i]+a[j]>a[k]&&k<=n)
                 k++;
                ans+=k-j-1;
                } 
全部代码如下
#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#define ll long longint n,a[6005];ll ans;using namespace std;int main(){   cin>>n;    for(int i=1;i<=n;i++)    cin>>a[i];    sort(a+1,a+n+1);    for(int i=1;i<=n-2;i++)        {   int k=i+2;             for(int j=i+1;j<=n-1;j++)           {                    while(a[i]+a[j]>a[k]&&k<=n)                 k++;                ans+=k-j-1;                }                  }           cout<<ans<<endl;        //while(1);return 0;}