ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【Codechef】Chef and Triangles -Problem Code: MAKETRI

2020-01-10 18:55:50  阅读:336  来源: 互联网

标签:A1 Code Ai ll Aj Chef A3 A2 MAKETRI


题面:

  小明已经厌倦了做菜,做菜对他来说太简单了。这天,他决定要挑战一下自己。 他已经选择了 N 根意大利面,准备做一道菜。他还需要选出一根意大利面,使得这根意大利面可以和已有的 N 根面中的某两根构成一个三角形。选出的意大利面的长度必须在 [L, R] 的范围内。 请你求出小明选择的方案数

输入:

  第一行给出N,L,R。 第二行给出N个数len1,len2,...,lenN,表示N个意大利面的长度。

  2<=N<=1e6 1<=L,R<=1e18,1<=leni<=1e18

输出:

  输出方案数。

样例:

Input:
5 1 4
1 2 3 4 5
Output:
3

这题卡了我很久。毕竟我之前没做过这一类的题目。

题意还是较为简单,不过就是从[L,R]的范围内能选出多少条条边与给出数组中的数凑成三角形
看到数据规模自然是不能暴力的,毕竟O(n2)加上1e6的规模必然会炸。

首先毕竟题目是要凑三角形,我们必然就能想到三角形的性质:
1.任意两边之和大于第三边
2.任意两边之差小于第三边

我们假设我们在[L,R]内取了x长度的边,之后又从给出的长度数组A中取了Ai与Aj长度的边。
易得到以下的式子:
·x + Ai > Aj ——> x > Aj - Ai
·x + Aj > Ai ——> x > Ai - Aj
·Ai + Aj > x ——> x < Ai + Aj
关于为什么是这三条式子,其实你就算写出了其他的也能化成这三条,我只是为了方便就拿了这样的式子。

所以我们就能很自然地想出,[L,R]与[max(Ai-Aj, Aj-Ai)+1, Ai+Aj-1]交集即为选取Ai与Aj的x的方案数。
上面的交集的意思就是既要在[L,R]范围内又要能与Ai和Aj组成三角形的范围。

但是关于怎么选取Ai与Aj确仍然是个问题。毕竟暴力的话还是O((R-L+1)*n2)。
这里引入一个很重要的结论:

假设这里有三个数A1 < A2 < A3,我们定义R(i,j)代表的是Ai,Aj能形成的三角形的范围。
所以
  R(1,2)=[A2-A1+1,A2+A1-1],
  R(2,3)=[A3-A2+1,A3+A2-1]
  R(1,3)=[A3-A1+1,A3+A1-1]。
R(2,3)是完全包含R(1,3)的。这个也是较为好证明的,毕竟两个更大更相近的数所形成的三角形的范围,必然是要比两个较小相距较远的数来的大的。
(具体可以自己举例证明)

有了这个结论后我们就可以先将A数组排序,之后通过n-1对R(j-1,j)的并集(1-n总共有n-1个j与j-1),再与[L,R]的交集即可以求出所求的方案数。
不过千万要注意特殊的情况,不然会WA很多发。

以下为AC代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
    long long n,l,r;
    scanf("%lld %lld %lld",&n,&l,&r);

    ll a[n];

    for(ll i=0;i<n;i++)
    scanf("%lld",&a[i]);
    sort(a,a+n);

    ll sum,diff,ans=0;
    if (l > r)
    {
        cout << ans << endl;
        return 0;
    }

    for(ll i=n-1;i>0;i--)
    {
        sum = a[i]+a[i-1]-1;
        diff = a[i]-a[i-1]+1;
        //这里直接求交集
        ll s = max(l,diff);
        ll d = min(sum,r);
        if (s <= d)
            ans += d-s+1;
        //把选用过的长度去掉
        r = min(r,diff-1);
    }

    printf("%lld\n",ans);

    return 0;
}
View Code

标签:A1,Code,Ai,ll,Aj,Chef,A3,A2,MAKETRI
来源: https://www.cnblogs.com/Vikyanite/p/12177631.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有