Mandel520 @ 2022-02-15 12:26:44
二分查找的思路是这样的:
首先读入所有学校的分数, 然后对所有学校的分数从小到大排序
然后依次读入所有学生的估分, 然后使用 upper_bound() 函数对当前估分进行二分查找. upper_bound()函数的返回值存入变量 idx, 表示数组中第一个比当前估分更大的值的下标
然后在下标为 idx 的值和下标为 idx - 1 的值之间找到和估分相差较小的值, 将分差累加给总分差
每次查找的结果有三种情况:
(1) 如果当前数组中存在一个和查找的估分相同的值, 则 idx - 1 就是和估分相同的值
(2) 如果当前数组中存在多个和查找的估分相同的值, 则 idx - 1 也是和估分相同的值
(3) 如果当前数组中不存在和查找的估分相同的值, 则 idx - 1是最后一个小于估分的值, idx 是第一个大于估分的值. 在这两个值中, 必定存在和估分分查最小的值
因此, 不管是上面哪种情况, idx 和 idx - 1 对应的值中都必定有一个是和估分相差最小的值
这种思路理论上是没有问题的, 但是除了样例以外都WA了
#include<bits/stdc++.h>
using namespace std;
int scoreline[1000005];
int scores[1000005];
int m, n;
long long sum = 0;
int main(){
cin >> m >> n;
for (int i = 1; i <= m; i++) cin >> scoreline[i]; //读入分数线
sort(scoreline + 1, scoreline + n + 1);
for (int i = 1; i <= n; i++){ //依次读入学生的估分
int score;
cin >> score;
int idx = upper_bound(scoreline + 1, scoreline + m + 1, score) - scoreline;
//判断边界
if (idx == 1) sum += abs(scoreline[idx] - score);
else if (idx == m + 1) sum += abs(scoreline[idx - 1] - score);
//取当前学校和前一个学校中分差较小的, 把分差加给总分差
else sum += min(abs(score - scoreline[idx - 1]), abs(score - scoreline[idx]));
}
cout << sum << endl;
return 0;
}
恳请各位大佬帮我看看问题出在哪
by CANTORSORT @ 2022-02-15 14:17:01
把 upper_bound
改成手打试试?
by CANTORSORT @ 2022-02-15 14:18:43
int l=0,r=m+1;
while(l<r)
{
int mid=(l+r)>>1;
if(scoreline[mid]<=score)
l=mid+1;
else
r=mid;
}
by CANTORSORT @ 2022-02-15 14:26:04
for (int i = 1; i <= m; i++)
cin>>scoreline[i]; //读入分数线
sort(scoreline + 1, scoreline + n + 1);
by CANTORSORT @ 2022-02-15 14:26:34
把 sort(scoreline + 1, scoreline + n + 1);
改成 sort(scoreline + 1, scoreline + m + 1);
by CANTORSORT @ 2022-02-15 14:27:47
一打错,千古恨!
by CANTORSORT @ 2022-02-15 14:28:08
跟二分没关系哈~
by Mandel520 @ 2022-02-15 22:37:35
@cantorsort2919 谢谢大佬 Orz
by FireDHK @ 2022-03-10 07:45:14
我的思路跟你的差不多,你的代码能过吗,我的总是有三个WA