TOJ 3750: 二分查找

3750: 二分查找 分享至QQ空间 去爱问答提问或回答

Time Limit(Common/Java):3000MS/9000MS     Memory Limit:65536KByte
Total Submit: 1925            Accepted:759

Description

将n个从小到大排序的整数(n<1000000)从1~n进行编号,并一个待查找的整数m,请使用二分法进行查找。

 

Input

 

输入包括3行,第一行为整数n,第二行包括n个整数,以空格分隔,第三行为整数m。

 

Output

 

如果能够在序列中找到整数m,则输出编号(如果存在多个编号,返回编号最小的),如果不存在,则输出None。

 

Sample Input

10
1 2 4 5 6 7 8 9 10 11
10
10
1 2 4 5 6 7 8 9 10 11
12

Sample Output

9
None

 

一个二分查找的数据结构题,第一次我竟然TLE了,这个会有重复的啊,所以重复我就向前搜索,这个TLE可能是我查询到中间的时候他就找到了,但是这个数确很靠前,所以借助了辅助数组就过了,那这个题也可以测试下移位运算符啊,但是我觉得这个移位运算符并没有快多少,所以我要想缩短时间还可以用lower_bound,但是速度也是没有提升太多的。想一下用map去重,map插入运算本来就要耗时,所以还是TLE了,所以好奇怪第一名究竟用了什么做法

一般二分

#include <stdio.h>
int a[1000005],b[1000005],n,t;
int BS(){
    int l=0,r=n-1;
    while(l<=r) {
        int m=(l+r)>>1;
        if(t<a[m])
            r=m-1;
        else {
            if(t>a[m])
                l=m+1;
            else
                return m;
        }
    }
    return -1;
}
int main(){
while(~scanf("%d",&n)){
    scanf("%d",&a[0]);
    b[0]=1;
    for(int i=1;i<n;i++){
    scanf("%d",&a[i]);
    if(a[i]==a[i-1])
    b[i]=b[i-1];
    else b[i]=i+1;}
    scanf("%d",&t);
    if(a[0]==t)
    puts("1");
    else{
    int f=BS();
    if(f!=-1){
    printf("%d\n",b[f]);
    }
    else
    puts("None");
    }}
return 0;
}

上面的二分用空间过多,继续二分下去,也就是看下左边和它相等么,但是这个速度也上不去,改下哈夫曼树的不同判断也不行

#include <stdio.h>
int a[1000005],n,t;
int BS(){
    int l=0,r=n-1;
    while(l<=r){
        int m=(l+r)>>1;
        if(t<a[m])
            r=m-1;
        else if(t>a[m])
        l=m+1;
        else if(a[m-1]<t)
        return m;
        else r=m-1;
    }
    return -1;
}
int main(){
while(~scanf("%d",&n)){
    for(int i=0;i<n;i++)
    scanf("%d",&a[i]);
    scanf("%d",&t);
    if(a[0]==t)
    puts("1");
    else{
    int f=BS();
    if(f!=-1){
    printf("%d\n",f+1);
    }
    else
    puts("None");
    }}
return 0;
}

库函数提供的二分

#include <stdio.h>
#include <algorithm>
using namespace std;
int a[1000000],n,t;
int main(){
while(~scanf("%d",&n)){
    for(int i=0;i<n;i++)
    scanf("%d",&a[i]);
    scanf("%d",&t);
    int f=lower_bound(a,a+n,t)-a;
    if(a[f]==t)
    printf("%d\n",f+1);
    else
    printf("None\n");
    }
return 0;
}

 

转载于:https://www.cnblogs.com/BobHuang/p/6963628.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值