[swustoj 1092] 二分查找的最大次数

二分查找的最大次数(1092)

问题描述

这里是一个在排序好的数组A(从小到大)中查找整数X的函数,返回值是查找次数。

int binarySearch(inta[],int n,int x)//数组,数组大小,查找的数据

{

      int cnt=0;

      int L=0,R=n-1,mid;

      while(true)

      {

            cnt++;

            mid=(L+R)/2;

            if(a[mid]==x) returncnt;

            elseif(x<a[mid])R=mid;

            else L=mid+1;

      }

    return -1;

}

现在的问题是,数组a中某些数据损坏了,我们只知道数组中的一部分数据和数组的大小N,我们想知道查找整数X最大的可能的查找次数,我们假设数组中每个数都不相同,且X一定出现在原数组中,a在被损坏前的是已经排好序的。

输入

多组测试数据,每组第一行是数组大小N(1<=N<=100000),第二行是这个数组的数,这个数组都是正数,-1表示这个数据被损坏。第三行是查找的正整数X。数据都在32位以内。

输出

X的最大查找次数。

样例输入

5
1 2 3 4 5
3
5
1 -1 -1 -1 5
3
5
-1 -1 -1 -1 -1
3

样例输出

1
2
3

好像没什么说的

#include <iostream>

#include <cstring>

#include <algorithm>

#include <cstdio>

using namespace std;

#define INF 0x3f3f3f3f

#define N 100010



int n,k;

int a[N];

int ans[N];



int bs(int k)

{

    int cnt=0;

    int l=0,r=n-1;

    while(l<=r)

    {

        cnt++;

        int m=(l+r)>>1;

        if(a[m]==k) return cnt;

        else if(k<a[m]) r=m;

        else l=m+1;

    }

}

int init()

{

    for(int i=0;i<n;i++) a[i]=i;

    for(int i=0;i<n;i++) ans[i]=bs(a[i]);

}

int main()

{

    while(scanf("%d",&n)!=EOF)

    {

        init();

        for(int i=0;i<n;i++) scanf("%d",&a[i]);

        scanf("%d",&k);



        //确定k的范围

        int L=0,R=n-1;

        for(int i=0;i<n;i++)

        {

            if(a[i]==-1) continue;

            if(a[i]<k) L=i+1;

            else if(a[i]==k)

            {L=R=i;break;}

            else if(a[i]>k)

            {R=i-1;break;}

        }

        int ret=0;

        for(int i=L;i<=R;i++)

        {

            ret=max(ret,ans[i]);

        }

        cout<<ret<<"\r\n";

    }

    return 0;

}

 

你可能感兴趣的:(二分查找)