• 二分板子


    Description

    用有序表表示静态查找表时,通常检索函数可以用折半查找来实现。
    折半查找的查找过程是:首先确定待查记录所在的范围,然后逐步缩小范围直到找到或者确定找不到相应的记录为止。而每次需要缩小的范围均为上一次的一半,这样的查找过程可以被称为折半查找。
    其查找过程可以描述如下:
     
    在本题中,读入一串有序的整数,另外给定多次查询,判断每一次查询是否找到了相应的整数,如果找到则输出整数相应的位置。

    Input

    输入的第一行包含2个正整数n和k,分别表示共有n个整数和k次查询。其中n不超过1000,k同样不超过1000。
    第二行包含n个用空格隔开的正整数,表示n个有序的整数。输入保证这n个整数是从小到大递增的。
    第三行包含k个用空格隔开的正整数,表示k次查询的目标。

    Output

    只有1行,包含k个整数,分别表示每一次的查询结果。如果在查询中找到了对应的整数,则输出其相应的位置,否则输出-1。
    请在每个整数后输出一个空格,并请注意行尾输出换行。

    Sample Input

    8 3
    1 3 5 7 8 9 10 15
    9 2 5

    Sample Output

    5 -1 2 

    HINT

    在本题中,需要按照题目描述中的算法完成折半查找过程。通过将需要查询的值与当前区间中央的整数进行比较,不断缩小区间的范围,直到确定被查询的值是否存在。

    通过课本中的性能分析部分,不难发现折半查找的时间复杂度为O(log2n),这是一种非常高效的查找方法。

    如果序列为单调递增序列:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <queue>
     9 #include <set>
    10 #include <stack>
    11 #include <map>
    12 #include <sstream>
    13 const int INF=0x3f3f3f3f;
    14 typedef long long LL;
    15 const int mod=1e9+7;
    16 const int maxn=1e5+10;
    17 using namespace std;
    18 
    19 int a[1005];
    20 
    21 int main()
    22 {
    23     int n,m;
    24     scanf("%d %d",&n,&m);
    25     for(int i=0;i<n;i++)
    26         scanf("%d",&a[i]);
    27     for(int i=0;i<m;i++)
    28     {
    29         int x;
    30         scanf("%d",&x);
    31         int l=0;
    32         int r=n-1;
    33         int mid;
    34         int flag=0; 
    35         while(l<=r)
    36         {
    37             mid=(l+r)>>1;
    38             if(a[mid]==x)
    39             {
    40                 flag=1;
    41                 break;
    42             }
    43             else if(a[mid]>x)
    44                 r=mid-1;
    45             else
    46                 l=mid+1;
    47         }
    48         if(flag==1)
    49             printf("%d ",mid);
    50         else 
    51             printf("-1 ");
    52     }
    53     printf("
    ");
    54     return 0;
    55 }

    递归写法:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <queue>
     9 #include <set>
    10 #include <stack>
    11 #include <map>
    12 #include <sstream>
    13 const int INF=0x3f3f3f3f;
    14 typedef long long LL;
    15 const int mod=1e9+7;
    16 const int maxn=1e5+10;
    17 using namespace std;
    18 
    19 int a[maxn];
    20 
    21 int Find(int L,int R,int x)
    22 {
    23     if(L>R)                //查找失败 
    24         return -1;
    25     int mid=(L+R)/2;
    26     if(a[mid]==x)        //找到直接返回 
    27         return mid;
    28     else if(a[mid]>x)    //大于待找元素则往左区间找 
    29         return Find(L,mid-1,x);
    30     else                //小于待找元素则往右区间找 
    31         return Find(mid+1,R,x);
    32 } 
    33 
    34 int main()
    35 {
    36     int n;//元素个数
    37     scanf("%d",&n);
    38     for(int i=1;i<=n;i++)//保证元素递增有序 
    39         scanf("%d",&a[i]);
    40     int x;//待查元素 
    41     scanf("%d",&x);
    42     int L=1,R=n;//初始化边界 
    43     int ans=Find(L,R,x);
    44     if(ans==-1)
    45         printf("查找失败
    ");
    46     else
    47         printf("%d
    ",ans);
    48     return 0;
    49 }

    如果序列为单调非递减序列(有重复值):

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <string>
    #include <math.h>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <stack>
    #include <map>
    #include <sstream>
    const int INF=0x3f3f3f3f;
    typedef long long LL;
    const int mod=1e9+7;
    const int maxn=1e5+10;
    using namespace std;
    
    int a[1005];
    
    int main()
    {
        int n,m;
        scanf("%d %d",&n,&m);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(int i=0;i<m;i++)
        {
            int x;
            scanf("%d",&x);
            int l=0;
            int r=n-1;
            int mid;
            while(l<r)
            {
                mid=(l+r)>>1;
                if(a[mid]<x)
                    l=mid+1;
                else
                    r=mid;
            }
            if(a[l]==x)
                printf("%d ",l);
            else 
                printf("-1 ");
        }
        printf("
    ");
        return 0;
    }

    在非递减序列中插入x

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <queue>
     9 #include <set>
    10 #include <stack>
    11 #include <map>
    12 #include <sstream>
    13 const int INF=0x3f3f3f3f;
    14 typedef long long LL;
    15 const int mod=1e9+7;
    16 const int maxn=1e5+10;
    17 using namespace std;
    18 
    19 int a[maxn];
    20 
    21 void Insert(int L,int R,int x,int (&a)[maxn],int n)//在元素个数为n的a[L,R]中插入X 
    22 {
    23     int pos=n;//待插位置初始化为n 
    24     while(L<=R)
    25     {
    26         int mid=(L+R)/2;
    27         if(a[mid]<x)
    28             L=mid+1;
    29         else
    30         {
    31             pos=mid;
    32             R=mid-1;
    33         }
    34     }
    35     for(int i=n;i>pos;i--)//腾位置 
    36     {
    37         a[i]=a[i-1];
    38     }
    39     a[pos]=x;//插入 
    40 }
    41 
    42 int main()
    43 {
    44     int n;//元素个数
    45     printf("请输入元素个数:"); 
    46     scanf("%d",&n);
    47     printf("请输入这些元素:
    "); 
    48     for(int i=0;i<n;i++)//保证元素为非递减序列,可以有重复值 
    49         scanf("%d",&a[i]);
    50     int x;//待插入元素
    51     printf("请输入待插入的元素:");
    52     scanf("%d",&x);
    53     int L=0,R=n-1;//初始化边界 
    54     Insert(L,R,x,a,n);//插入 
    55     printf("插入后序列为:
    ");
    56     for(int i=0;i<=n;i++)
    57     {
    58         printf("%d ",a[i]);
    59     }
    60     printf("
    ");
    61     return 0;
    62 }
  • 相关阅读:
    FastDFS安装配置过程中出现错误提示"/home/yuqing/fastdfs" can't be accessed, error info: No such file or directory
    dubbo-monitor安装监控中心,管理控制台安装网页一直访问不到,解决bug的方式记录
    dubbo-monitor安装监控中心,管理控制台安装
    zookeeper伪分布式集群安装
    zookeeper单节点安装
    JedisCluster操作redis集群demo
    Redis Cluster集群的搭建
    redis3.0.6安装配置
    Windows注册表中修改CMD默认路径
    eclipse中使用mybatis-generator逆向代码生成工具问题解决记录
  • 原文地址:https://www.cnblogs.com/jiamian/p/11956993.html
Copyright © 2020-2023  润新知