统计好元组(牛客编程巅峰赛S2第12场 - 青铜&白银&黄金)

题目描述

现在给定一个数组arr,和a,b两个数字,你要做的就是找到(i,j,k)。且满足 
    1. 0 <= i < j < k < arr.size()
    2. |arr[i] - arr[j]| <= a
    3. |arr[j] - arr[k]| <= b
统计满足条件的个数并返回(最后结果可能很大,请取1000000007的余数)。

示例

输入

  [7,1,8,9,0],3,3

返回值

  1

说明

  只有(7,8,9)符合要求

备注

  arr.size() <= 5000

  其余变量均<=1e9

思路&&感想

  挺简单的乘法定理,但是一开始思路没换过来

  一开始以第一个数为切入点想了个O(n^3)模拟,TLE了

  最后看题解要转变一下切入点,以一组数中的第二个数为切入点,左边符合条件的为k有x种情况,右边符合条件的为i有y种情况

  这样最后的答案就为x*y

  赛后偷看了队内大佬wlx的代码又发现了新思路

  以第一个数为切入点,枚举到arr.size()-3,把每一组的第一个数都遍历一遍

  在每个i里边从他后边一个元素开始枚举到arr.size()-2,每一种符合情况的j都在相应的数组中++

  之后再从第二个数开始枚举到arr.size()-2,把每一组的第二个数都遍历一遍

  在从其中后边一个元素枚举到arr.size()-1,只要符合条件就在计数器里边++

AC代码

思路一 

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param arr int整型vector 
     * @param a int整型 
     * @param b int整型 
     * @return int整型
     */
    int countTriplets(vector<int>& arr, int a, int b) {
        long long ans=0;
        int n=arr.size();
        for(int i=0;i<n;i++)
        {
            long long x=0,y=0;
            for(int j=i+1;j<n;j++)
            {
                if(abs(arr[i]-arr[j])<=b) x++;
            }
            for(int j=i-1;j>=0;j--)
            {
                if(abs(arr[i]-arr[j])<=a) y++;
            }
            ans+=x*y;
        }
        return (int)(ans%1000000007);
    }
};

思路二

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 
     * @param arr int整型vector 
     * @param a int整型 
     * @param b int整型 
     * @return int整型
     */
    int countTriplets(vector<int>& arr, int a, int b) {
        int x[5010]={0};
        long long ans=0;
        for(int i=0;i<=arr.size()-3;i++)
        {
            for(int j=i+1;j<=arr.size()-2;j++)
            {
                if(abs(arr[i]-arr[j])<=a) x[j]++;
            }
        }
        for(int i=1;i<=arr.size()-2;i++)
        {
            int sum=0;
            for(int j=i+1;j<=arr.size()-1;j++)
            {
                if(abs(arr[i]-arr[j])<=b) sum++;
            }
            ans+=sum*x[i];
        }
        return (int)(ans%1000000007);
    }
};

 

posted @ 2020-12-23 23:07  TheWeak  阅读(71)  评论(0编辑  收藏  举报