首页 > 其他分享 >二分

二分

时间:2023-03-11 16:58:10浏览次数:53  
标签:二分 Code int else while maxn

情况导入

如果在生活中,有一个人,让你猜在 \(1\) 到 \(100\) 之间的一个数,你该怎么猜?

假设答案是 \(20\),那我们应该这样猜:

先猜 \(50\),大了。

随后猜 \(25\),还是大了。

再猜 \(15\),小了。

最后猜 \(20\),对了。

我们其实可以发现,能最快猜到的办法肯定是在一个区间中取中间数查找。

那我们在编程中也可以如此,例如在数组 \(a\) 中查找一个数,那我们也应该这么找(这样的前提是必须具有单调性的),在很多个下标中选取中间的那个来搜。大了,就往左边搜,小了,就往右边搜。

Code

代码也很简单,就跟刚刚说的相似:

//核心代码
while(l<=r){
    int m=(l+r)>>1;
    if(a[m]>=x)p=m,r=m-1;
    else l=m+1;
}

题目实战

洛谷P2249

题目大意:

现在有 \(n\) 个数,有 \(m\) 个查询,问你在这 \(n\) 个数中,出现的下标是多少?

思路

可以直接套用二分模板,找到后输出就可以了。

Code

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int maxn=1e6+10;
int a[maxn];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        cin >> a[i];
    }
    for(int i=0;i<m;++i){
        int x;
        cin >> x;
        int l=1,r=n,p=n+1;
        while(l<=r){
            int m=(l+r)>>1;
            if(a[m]>=x)p=m,r=m-1;
            else l=m+1;
        }
        if(p<=n && a[p]==x)cout << p << " ";
        else cout << -1 << " ";
    }
    return 0;
}

洛谷 P1102

题目大意

给你一串数 \(a\),和一个数字 \(c\),使得 \(a\) 数组中的两个数相减等于 \(c\)。

思路

同理,我们枚举 \(a_i\),再二分 \(a_i-c\)即可。

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int n,c,a[maxn];
long long ans;
int find(int x){
    int l=1,r=n,p=n+1;
    while(l<=r){
        int m=(l+r)>>1;
        if(a[m]>=x)p=m,r=m-1;
        else l=m+1;
    }
    if(p<=n && a[p]>=x)return p;
    else return 0;
}
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 k=a[i]-c;
        int p=find(k),q=find(k+1);
        ans+=(q-p);
    }
    cout << ans << endl;
    return 0;
}

总结

想二分这种题,我们要多多练习,理解每一行的意思。

感谢观看。

标签:二分,Code,int,else,while,maxn
From: https://www.cnblogs.com/shine0709/p/17206393.html

相关文章

  • 二分法查找
    原理一个数据有升序的数组,每次取中间元素比较,如果大于需要查找的元素,则去后面数据,中间数据作为起点最后数据作为终点再定中间数据比较。如果小于需要查找的数据,则取前面......
  • 二分图
    最大匹配最基本的东西,可以用dinic在\(\mathcal{O}(m\sqrtn)\)的时间内解决。Hall定理判断二分图是否存在完美匹配的定理。默认左部点数小于等于右部点数,定义\(N......
  • 整体二分板子
    P3834可持久化线段树2静态区间第\(k\)小。存个不带修整体二分板子。离散化,拿树状数组维护一下元素出现次数。假设当前区间内所有答案都是\(mid\)。实时更新,这样......
  • 算法基础课笔记:第一章,基础算法 排序 + 二分
    这节课的内容排序快排归并排序二分整数二分浮点数二分如何提高自己敲模板的熟练度呢?反复的练,孰能生巧。重复3-5次。快排1.确定分界点2.调整区......
  • 二分法
      #include<iostream>usingnamespacestd;constintN=1e5+10;inta[N],st[N];intnum=0;intmain(){intn,q;cin>>n>>q;for(inti=1;i<=n;i++){cin>>a[i];......
  • 整数二分的边界条件
     有单调性的题目一定可以二分,没有单调性的可能可以二分,二分和单调性没有直接关系。整数二分的本质是边界,整个区间可以一份为二,一半满足一半不满足,则二分即可以找前一半......
  • 这个二分查找好难(Drying)
    DryingItisveryhardtowashandespeciallytodryclothesinwinter.ButJaneisaverysmartgirl.Sheisnotafraidofthisboringprocess.Janehasdecided......
  • HDU2199 Can you solve this equation? (二分查找)
    Canyousolvethisequation?TimeLimit:2000/1000MS(Java/Others)    MemoryLimit:32768/32768K(Java/Others)TotalSubmission(s):12794    AcceptedS......
  • 环形链表(哈希表、链表)、寻找两个正序数组的中位数(数组、二分查找)、二进制求和(位
    环形链表(哈希表、链表)给定一个链表,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。为了表示给定链表中的环,我们使用整......
  • 【二分查找】LeetCode 4. 寻找两个正序数组的中位数
    题目链接4.寻找两个正序数组的中位数思路分治代码classSolution{publicdoublefindMedianSortedArrays(int[]nums1,int[]nums2){if(nums1.len......