Codeforces Round #690 (Div. 3) E1. Close Tuples (easy version) (贪心+思维)

https://codeforces.com/contest/1462/problem/E1

E1. Close Tuples (easy version)

题目大意:

给定一个长度为n的序列a,由1到n的整数组成,某些元素可能相等。

找出m=3个元素的元组的数目,使得元组中的最大数目与最小值相差不超过k=2。

输出数量。
input 
4
4
1 2 4 3
4
1 1 1 1
1
1
10
5 6 1 3 2 9 8 1 2 4
output 
2
4
0
15

因为每一个数字都有它自己唯一的位置编号,所以我们对它进行排序后再做运算对结果没有影响,先固定左边界,右划寻找右边界
先找到最大的那个,然后依次左边界依次右滑,以此计算个数:(固定右边界再划左边界比固定左边界画右边界计数更好,因为不用再倒回来重新计算)
3 4 5 6 7......
1 3 6 10 15...... (每次增加一个单位的长度增加的个数:1* 2/2;2* 3/2;3* 4/2;4* 5/2;5* 6/2......)
1 4 10 20 35......
这个求个数的式子肥肠重要,要记住!
ans+=(LL)(j-i)*(j-i-1)/2;

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const LL MAXN=1e18;
const LL N=500200,M=2002;
LL a[N];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    LL T=1;
    cin>>T;
    while(T--)
    {
        LL n;
        cin>>n;
        LL m=3,k=2;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        sort(a+1,a+1+n);
        LL ans=0;
        for(int i=1,j=1;i<=n;i++)
        {
            while(j<n&&a[j+1]-a[i]<=k) j++;
            if(j-i>=2)
            {
                ans+=(LL)(j-i)*(j-i-1)/2;
               // cout<<i<<" "<<j<<" "<<ans<<endl;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
posted @ 2022-12-29 21:22  Vijurria  阅读(15)  评论(0编辑  收藏  举报