"科林明伦杯"哈尔滨理工大学第八届程序设计竞赛——Hrbust -2373 小C的问题(利用斐波那契数列规律判断三边关系是否构成三角形)

Description
小C是一个可爱的女孩,她特别喜欢世界上最稳定的图形:三角形。有一天她得到了n根木棍,她把这些木棍随意的摆放成一行。小K来和小C玩,他发现了这排木棍,突然想知道在一段区间[l,r]之间的木棍(即第L根到第R根木棍)是否可以组成一个三角形,小C表示她不会,所以请你帮忙。

Input
数据只有一组。

第一行只有一个数字N,代表一共有N根木棍,N<=100000。

第二行为N个数,代表每根木棍的长度。每根木棍的大小不超过1e18。

第三行为一个数字Q,代表询问数目,Q<=100000。

接下来的Q行,每一行有两个数字L和R,代表询问的区间。其中L和R满足1<=L<=R<=N。

Output
对于每个询问,如果可以组成三角形输出”Yes”,否则输出”No”(不需要加引号)。

Sample Input
5

3 1 2 4 5

2

1 3

1 5

Sample Output
No

Yes

题意:给出一段序列,在序列中选择一一段区间,在区间中任选3个值作为三条边,判断是否能构成三角形。

思路:首先对于三角形三边规律,两边之和必大于第三边,因此理论上我们只要找到两个较短边求和后与最长边比较即可。由于数列是乱序的,数列中每个值小于1e18,数列长度和区间询问次数都是1e5,不可能暴力查询。此处想到,因为两边之和一定要大于第三边,因此当数列满足,排序后,较小两边相加都小于等于下一条边,这种序列即斐波那契数列,甚至比斐波那契数列更容易增大的数列。

反过来想想,既然构造一个超长的不能满足构成三角形的数列必须最低限度是构造一个斐波那契数列,那么这个数列长度能否构造得很长?不行,因为斐波那契数列到第100个就超过1e10了。
因为数列中所有值都小于1e18,因此任何区间大于100的长度,必定存在能构造出三角形的三边,100以内的,直接区间排序后暴力查找是否存在能构成三边的三角形即可。

#include<stdio.h>
#include<algorithm>
#define LL long long
using namespace std;
struct node
{
    LL v;
    int id;
}a[100005];
bool cmp(node a,node b)
{
    return a.v<b.v;
}
bool cmpid(node a,node b)
{
    return a.id<b.id;
}
int main()
{
    int n,m,l,r;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0; i<n; i++) scanf("%lld",&a[i].v),a[i].id=i;
        scanf("%d",&m);
        while(m--)
        {
            scanf("%d%d",&l,&r);
            l--;
            r--;
            if(r-l+1>=100)
            {
                printf("Yes
");
                continue;
            }
            else
            {
                bool flag=false;
                sort(a+l,a+r+1,cmp);
                for(int i=l; i<=r-2; i++)
                {
                    if(a[i].v+a[i+1].v>a[i+2].v)
                    {
                        flag=true;
                        printf("Yes
");
                        break;
                    }
                }
                if(!flag)printf("No
");
                sort(a+l,a+r+1,cmpid);
            }
        }
    }
}
原文地址:https://www.cnblogs.com/kuronekonano/p/11135813.html