二进制搜索中的一段代码在c++中似乎有问题

binary search in a piece of code in c++ seems to have problems

本文关键字:代码 c++ 有问题 一段 搜索 二进制      更新时间:2023-10-16

我参加了一个在线的本地模拟比赛,在实现其中一个问题时遇到了一个问题。问题是:

<标题>

鼹鼠的午饭时间到了。他的朋友土拨鼠为他准备了一顿美味的午餐。

土拨鼠给鼹鼠带来n堆有序的蠕虫,每堆有ai条蠕虫。他用连续整数标记了所有这些蠕虫:第一堆的蠕虫被标记为1到a1,第二堆的蠕虫被标记为a1 + 1到a1 + a2,以此类推。请参阅示例以更好地理解

鼹鼠不能吃所有的蠕虫(土拨鼠带来了很多),我们都知道,鼹鼠是盲人,所以土拨鼠告诉他最好的多汁蠕虫的标签。如果鼹鼠说对了,土拨鼠才会给鼹鼠一只虫子。

可怜的鼹鼠请求你的帮助。对于土拨鼠说的所有多汁的虫子,告诉鼹鼠正确的答案。

输入

第一行包含单个整数n(1≤n≤105),即桩数。

第二行包含n个整数a1, a2,…, an(1≤ai≤103,a1 + a2 +…+ an≤106),其中ai为第i堆的虫数。

第三行包含单个整数m(1≤m≤105),即Marmot所说的多汁蠕虫的数量。

第四行包含m个整数q1, q2,…, qm(1≤qi≤a1 + a2 +…+ an),多汁蠕虫的标签。

<标题> 输出

打印m行到标准输出。第i行为整数,表示以数字qi标记的蠕虫所在的桩数。

<标题>示例输入输入

5

2 3 4 9

3

1 25 11

<标题> 输出1

5

3


下面是我的代码:

#include <iostream>
using namespace std;
int main(){
    int n, m; //as mentioned in Q
    cin >> n;
    int *a = new int[n]; //as said in Q
    for(int i = 0; i < n; i++)
        cin >> a[i];
    cin >> m;
    int *q = new int[m]; //as said in Q
    for(int i = 0; i < m; i++)
        cin >> q[i];
    int *sum = new int[n];
    sum[0] = a[0];
    for(int i = 1; i < n; i++)
        sum[i] = a[i] + sum[i - 1];
    for(int i = 0; i < m; i++){
        int low = 0, high = n - 1, mid;
        while(low <= high){ //here is where I believe has got a problem
            mid = (low + high) / 2;
            if(q[i] >= sum[mid] && q[i] < sum[mid + 1]){
                cout << mid + 1 << endl;
            }
            if(q[i] < sum[mid])
                high = mid - 1;
            else
                low = mid + 1;
        }
    }
    return 0;
}
我不明白问题到底是什么。有人能帮我一下吗?

Thanks in advance

<标题>编辑:在我的例子中,这个示例测试的输出是1。然而,当我试图在while块完成时打印出mid时,我得到了正确的mid值!

您的二进制搜索的问题是,您不处理的情况下,它未能找到它正在寻找的数字。

您的sum数组保存[2, 9, 12, 16, 25],但是当您寻找1时,它(非常正确地)找不到它,因为它不在2 - 25的范围内。

修复它的一个简单方法是在sum的开头添加一个额外的条目,以便它包含[0, 2, 9, 12, 16, 25],然后您的二进制搜索应该找到任何(有效)数字。记得增加sum数组的大小,以及初始的high值。

另一种解决方法是在找到正确的数字时设置一个标志。然后,如果您没有找到该数字,则可以假定它在第一堆中(如果您不需要处理无效输入)。

首先,让它工作。那就快点。

用简单的线性扫描替换二分查找,您很快就会发现您写下的条件是不正确的。例如,蠕虫1在第一堆中。考虑到问题条件,我希望线性扫描足够快,可以工作。