You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:用Binary Search解决Codeforces饮品问题时结果偏差(非超时)

问题分析与修正

你的代码结果少1的核心原因是二分查找逻辑不严谨,具体问题如下:

错误点拆解

  1. 提前终止循环:当找到prices[mid] == m时直接break,此时mid只是某个等于m的元素位置,而非最后一个小于等于m的元素索引。若数组存在多个等于m的元素,会漏掉后续符合条件的商店数量。
  2. 多余的mid更新:循环内手动执行mid = (l+r)//2完全多余,每次循环开头会重新计算mid,这会干扰最终mid的取值逻辑。
  3. 循环结束后的判断逻辑错误:当循环因l > r自然退出时,mid的取值是最后一次循环的中间值,已不符合当前l和r的范围,此时用prices[mid] <= m判断会出现偏差。

修正后的代码(两种实现方式)

方式1:找第一个大于m的元素位置(推荐)

利用二分查找找upper_bound(第一个大于目标值的元素索引),该索引即为符合条件的商店总数(因为数组已排序,前面所有元素都<=m):

n = int(input())
prices = list(map(int, input().split()))
prices.sort()

q = int(input())
for _ in range(q):
    m = int(input())
    l, r = 0, n  # 左闭右开区间
    while l < r:
        mid = (l + r) // 2
        if prices[mid] > m:
            r = mid
        else:
            l = mid + 1
    print(l)

方式2:找最后一个<=m的元素索引

记录最后一个满足prices[mid] <= m的索引,最终结果为该索引+1(若不存在则为0):

n = int(input())
prices = list(map(int, input().split()))
prices.sort()

q = int(input())
for _ in range(q):
    m = int(input())
    l, r = 0, n - 1
    last_valid = -1
    while l <= r:
        mid = (l + r) // 2
        if prices[mid] <= m:
            last_valid = mid
            l = mid + 1  # 尝试向右寻找更靠后的符合条件元素
        else:
            r = mid - 1
    print(last_valid + 1 if last_valid != -1 else 0)

逻辑说明

  • 两种方式都基于排序后的数组,保证二分查找的正确性。
  • 方式1的左闭右开区间写法更简洁,避免了边界条件的复杂判断,适合大规模数据(符合题目n和q均为1e5的要求)。

内容的提问来源于stack exchange,提问作者NetherXp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 21:35:53