挑战程序设计竞赛 1.61 nlogn算法

来源:互联网 发布:华大基因 知乎 编辑:程序博客网 时间:2024/06/05 14:31

问题如下:

  

 OK,这道题非常简单,朴素算法我就不说了,书上也给出了朴素O(n^3)的代码,但是同时也告诉我们还有更高效的算法,我当时琢磨了一下,排序,确定其中两个再用二分查找可以的到一个O(n^2logn)的算法,但是同样不高效。然后,然后.....

我发现这道题居然是一道贪心......

怎么贪呢?

代码如下:

#include<cstdio>#include<algorithm>#include<cstdlib>#include<cmath>#include<cstring>#include<queue>#include<string>#include<map>#include<set>#include<iostream>#include<ostream>#include<istream>#include<vector>#include<functional>#define ll long long;const int inf=0x3f3f3f3f;using namespace std;const int maxn=1005;int edge[maxn];int main(){    int n;    cin>>n;    for(int i=0;i<n;i++)    {        scanf("%d",&edge[i]);    }    sort(edge,edge+n);    bool flag=0;    for(int i=n-1;i>=2;i--)    {        if(edge[i]<edge[i-1]+edge[i-2])        {            flag=1;            cout<<edge[i]+edge[i-1]+edge[i-2]<<endl;            break;        }    }    if(!flag)cout<<0<<endl;    return 0;}
为什么这个算法是正确的呢?我们来证明一下

第一:edge[i],edge[i-1],edge[i-2]能构成三角形,不多说它肯定周长最大;

第二:如果它们不能构成,edge[i]为最大的三角形一定不能找到另外两条使其构成三角形的边,为什么呢?相信你已经清楚了,那就是edge[i-1]+edge[i-2]>其他任意俩边之和。

0 0