1 条题解

  • 0
    @ 2024-10-11 22:15:22

    观察题目中给定的三个条件:

    ages[y]0.5×ages[x]+7ages[y]≤0.5×ages[x]+7

    ages[y]>ages[x]ages[y]>ages[x]

    ages[y]>100ages[x]<100ages[y]>100∧ages[x]<100

    可以发现,条件 3 是蕴含在条件 2 中的,即如果满足条件 3 那么一定满足条件 2。因此,我们当条件 1 和 2 均不满足时,用户 x 就会向用户 y 发送好友请求,也就是用户 y 需要满足:

    0.5×ages[x]+7<ages[y]ages[x]0.5×ages[x]+7<ages[y]≤ages[x]ages[x]14ages[x]≤14 时,不存在满足要求的 ages[y]ages[y]。因此我们只需要考虑 ages[x]15ages[x]≥15 的情况,此时满足要求的 ages[y]ages[y] 的范围为 (0.5×ages[x]+7,ages[x]](0.5×ages[x]+7,ages[x]]

    ages[x]ages[x] 增加时,上述区间的左右边界均单调递增,因此如果我们将数组 agesages 进行升序排序,那么就可以在遍历 ages[x]ages[x] 的同时,使用两个指针 leftleftrightright 维护满足要求的 ages[y]ages[y] 的左右边界。当 xx 向后移动一个位置时:

    如果左边界指针 leftleft 指向的元素不满足 ages[left]>0.5×ages[x]+7ages[left]>0.5×ages[x]+7,那么就将左边界向后移动一个位置;

    如果右边界指针 right 指向的下一个元素满足 ages[right+1]ages[x]ages[right+1]≤ages[x],那么就将右边界向后移动一个位置。

    这样一来,[left,right][left,right] 就是满足年龄要求的 yy 的下标。需要注意的是,xx 本身一定在 [left,right][left,right] 区间内,因此 xx 发送的好友请求数,即为 [left,right][left,right] 区间的长度减去 1。

    我们将每一个x x 对应的[left,right] [left,right] 区间长度减去 1 进行累加,就可以得到最终的答案。

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int n;
    	cin>>n;
    	vector<int> ages(n);
    	for(int i=0;i<n;i++)cin>>ages[i];
    	sort(ages.begin(), ages.end());
    	int left = 0, right = 0, ans = 0;
    	for (int age: ages) {
                if (age < 15) {
                    continue;
                }
                while (ages[left] <= 0.5 * age + 7) {
                    ++left;
                }
                while (right + 1 < n && ages[right + 1] <= age) {
                    ++right;
                }
                ans += right - left;
            }
        cout<<ans;
    }
    
    • 1

    信息

    ID
    116
    时间
    1000ms
    内存
    256MiB
    难度
    7
    标签
    递交数
    76
    已通过
    16
    上传者