首页 > 其他分享 >洛谷题单指南-二分查找与二分答案-P1102 A-B 数对

洛谷题单指南-二分查找与二分答案-P1102 A-B 数对

时间:2024-02-29 12:00:40浏览次数:32  
标签:二分 P1102 int res 数对 mid long 指针

原题链接:https://www.luogu.com.cn/problem/P1102

题意解读:寻找A-B=C的数对数量,C大于0,B一定比A小,枚举B,找A是否存在即可。

解题思路:

先将数据由小到大排序,接下来介绍两种方法:二分、双指针

1、二分

枚举第1~n-1个数,作为B,寻找A=B+C的数量,只需要通过二分查找第一A和最后一个A的位置l、r,数量为r-l+1,进行累加即可。

100分代码:

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

const int N = 200005;

int a[N], n, c;
long long ans;

int bs1(int x)
{
    int res;
    int l = 1, r = n;
    while(l <= r)
    {
        int mid = (l + r) >> 1;
        if(a[mid] >= x) res = mid, r = mid - 1;
        else l = mid + 1;
    }
    if(a[res] == x) return res;
    return -1;
}

int bs2(int x)
{
    int res;
    int l = 1, r = n;
    while(l <= r)
    {
        int mid = (l + r) >> 1;
        if(a[mid] <= x) res = mid, l = mid + 1;
        else r = mid - 1;
    }
    if(a[res] == x) return res;
    return -1;
}

int main()
{
    cin >> n >> c;
    for(int i = 1; i <= n; i++) cin >> a[i];

    sort(a + 1, a + n + 1);

    for(int i = 1; i < n; i++)
    {
        int A = a[i] + c;
        int l = bs1(A), r = bs2(A);
        if(l != -1 && r != -1) ans += r - l + 1;
    }
    cout << ans;

    return 0;
}

2、双指针

指针i从1开始所指元素a[i]表示B,指针j从2开始所指元素a[j]表示A,

如果a[j]-a[i]<C,j往后走

如果a[j]-a[i]>C,i往后走

如果a[j]-a[i]=C,计算相同的a[j]、a[i]有多少个,相乘即为当前A-B=C数对的数量,累加即可

100分代码:

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

const int N = 200005;

int a[N], n, c;
long long ans;

int main()
{
    cin >> n >> c;
    for(int i = 1; i <= n; i++) cin >> a[i];

    sort(a + 1, a + n + 1);

    for(int i = 1, j = 2; i < n; i++) //双指针,i从1开始,j从2开始,a[i]表示B,a[j]表示A
    {
        while(a[j] - a[i] < c && j <= n) j++; //如果A-B<C,j往后走
        if(a[j] - a[i] == c) //如果A-B=C
        {
            int cntA = 1, cntB = 1;
            while(a[i + 1] == a[i] && i + 1 < n) i++, cntB++; //找B的数量,i移到相同值的最后一个
            while(a[j + 1] == a[j] && j + 1 <= n) j++, cntA++; //找A的数量,j移到相同值的以后一个
            ans += 1ll * cntA * cntB; //cntA * cntB即当前A-B=C的对数
        } 
    }

    cout << ans;

    return 0;
}

 

标签:二分,P1102,int,res,数对,mid,long,指针
From: https://www.cnblogs.com/jcwy/p/18043197

相关文章

  • CF514D R2D2 and Droid Army(二分,ST表)
    传送门解题思路直接二分能干掉的人数,然后check函数枚举所有区间,因为m很小,所以可以用m个ST表预处理每个区间对应每个属性的最大值。一是需要注意二分的写法,而是注意check(0)时候的特判。AC代码#include<iostream>#include<algorithm>#include<cmath>#include<cstdio>#......
  • 洛谷题单指南-二分查找与二分答案-P2249 【深基13.例1】查找
    原题链接:https://www.luogu.com.cn/problem/P2249题意解读:找有序数组中某个数第一次出现的位置,二分模版题,由于是二分板块的第一题,有必要对二分的各种模版进行介绍。解题思路:关于二分的一切:1、二分的本质二分的本质,是通过某种判定把目标范围划分成两个区间二分问题通常有两......
  • 二分查找——修补木桶
    修补木桶-HihoCoder1362-VirtualJudge(vjudge.net)#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>usingnamespacestd;#defineintlonglong#defineQAQ0constintN=2e5+5,inf=0x3f3f3f3f,mod=1e7+7;int......
  • 达梦、Oracle、Mysql和PostgreSQL数据库重要参数对比
    前言数据库在安装完成之后通常都会配置一些基础的参数用于控制和管理数据库行为,其中有些参数在配置完成后若要修改则需要重启数据库才能生效,甚至一些参数在完成初始化之后无法修改,这些参数在生产环境中尤其需要关注,需要事先就确定好,避免后续遇到需要修改时影响到生产环境的使用。......
  • 【算法】关于最长递增子序列(LIS)二分+贪心解法
    前言我们都知道,解决LIS的常规解法为DP,时间复杂度为O(n^2),但是在一些条件苛刻的问题中,通常DP的解法会超时。那么,是否存在一种时间复杂度更优秀的解法呢?答案是肯定的,有一种二分加贪心的解法可以将时间复杂度降低为O(nlogn)。详解如果我们现在要求下面这一组数据的LIS:我们需......
  • LeetCode二分查找 swift 面试
     funcbinarySearch(_array:[Int],_target:Int)->Int?{varleft=0varright=array.count-1whileleft<=right{letmid=(left+right)/2ifarray[mid]==target{returnmid......
  • 704. 二分查找C
    现在开始刷代码随想录里的题了。intsearch(int*nums,intnumsSize,inttarget){inthead=0,tail=numsSize-1;while(head<=tail){intmid=(head+tail)/2;if(nums[mid]<target){head=mid+1;}elseif(nums[mid]>target){......
  • #分块,二分#洛谷 5356 [Ynoi2017] 由乃打扑克
    题目支持区间加和区间查询第\(k\)小分析分块之后给每个整块排序,这样修改的时候整块打标记,散块直接分开把需要加的部分暴力加之后归并,就是\(O(\sqrt{n})\)的查询的话,如果只有散块直接归并出结果,否则二分答案,加上小块合并成的整块,相当于是整体二分,就是\(O(\sqrt{n}\log{a_......
  • Toyota Programming Contest 2024#2(AtCoder Beginner Contest 341)D - Only one of two
    目录链接题面题意题解代码总结链接D-Onlyoneoftwo题面题意求第\(k\)个只能被\(N\)或\(M\)整除的数题解\([1,x]\)中的能被\(n\)整除的数有\(\lfloor\frac{x}{n}\rfloor\)个\([1,x]\)中的能被\(m\)整除的数有\(\lfloor\frac{x}{m}\rfloor\)个\([1,x]\)中的能被\(n\)......
  • Python数据结构与算法05——二分查找
    二分查找——递归版:defbinarySearch(aimlist,item):#获取列表的长度n=len(aimlist)#如果列表非空ifn>0:#计算中间索引mid=n//2#如果中间元素是目标元素,则找到了ifaimlist[mid]==item:......