C艹,样例都过不了···,蒟蒻求助

P2249 【深基13.例1】查找

FengYuXinMing @ 2023-05-27 10:32:21

//来自洛谷P2249 【深基13.例1】查找
#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e6 + 5;
int a[maxn],n,m;

int change(int s){//二分
    int left = 1, right = n, mid;
    while(left <= right){
        mid = (left+right)/2;
        if (a[mid] = s)
            right = mid - 1;
        else if (a[mid] < s)
            left = mid + 1;
    }
    if (a[mid] == s){
        return mid;
    }
    return -1;
}
int main() {
    cin>>n>>m;
    for (int i = 1; i <= n;i++) cin >> a[i];
    for (int i = 1;i <= m;i++){
        int q;
        cin >> q; 
        int ans = change(q);
        cout << ans << ' ';
    }
    return 0;
}

by LiJoQiao @ 2023-05-27 10:40:51

由于二分第一次找到的数不一定是第一次出现(左边可能还有) 所以会出错


by LiJoQiao @ 2023-05-27 10:42:15

解决方法:
在change这个函数内部定义一个新变量来存储位置,如果mid>s或mid<s就缩小范围,当mid==s时更新一下这个存储位置的变量,然后向左继续搜索(右侧搜到的答案都是错的,留给lz思考)


by LiJoQiao @ 2023-05-27 10:42:45

我的代码

int check(int num)
{
    int l=1,r=n,mid=(l+r)>>1,loc=-1;//区间初始为[1,n]
    while(l<=r)//查找
    {
        mid=(l+r)>>1;//折半查找
        if(a[mid]>=num)
        {
            if(a[mid]==num)//等于则更新位置
            {
                loc=mid;
            }
            r=mid-1;
        }
        else//a[mid]小于num
        {
            l=mid+1;
        }
    }
    return loc;//返回位置
}

by FengYuXinMing @ 2023-05-27 19:52:49

@LiJoQiao 谢谢,我回头再看一下


by FengYuXinMing @ 2023-05-28 19:34:56

@LiJoQiao dalao">>"是表示什么作用


by FengYuXinMing @ 2023-05-28 19:45:52

@LiJoQiao 我明白了,二分查找第一次查到的不一定是第一次出现的,所以暂时储存,然后再循环一遍,看看左边是不是还有,还有的话第一次就是错误的,所以要存起来,谢谢奆佬!!!

ctj


by LiJoQiao @ 2023-05-29 18:08:32

@ababbjxzt >>是位运算符,int类型的变量整体右移n位相当于整除2的n次方


by LiJoQiao @ 2023-05-29 18:08:59

@ababbjxzt 不要ctj啊喂!


by FengYuXinMing @ 2023-05-29 19:45:10

@LiJoQiao (直接copy到主页储存器里面,小本本记下来)


by FengYuXinMing @ 2023-05-29 19:45:32

@LiJoQiao 现在可以了吗?doge


|