本题链接:
https://www.jisuanke.com/course/3797/255499
这题的大意是给你一个非降序列,再给你个x,叫你求最接近x的元素
这题很多萌新一看就说:“简单,一个lower_bound解决所有问题。”
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int num[100005];
int main() {
freopen("closest.in", "r", stdin);
freopen("closest.out", "w", stdout);
int n, m, x;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> num[i];
}
cin >> m;
int p1;
while (m--) {
cin >> x;
p1 = lower_bound(num, num + n, x) - num;
cout << p1 << endl;
}
return 0;
}
结果…

那么,到底怎么回事呢?
第一步,检查思路。
用lower_bound是没有问题的,但只用lower_bound就会有漏洞。
举个例子,看看这个样例:
3
2 5 8 12
1
9
正确输出是8,但用cpp跑一遍就会知道输出是12。
为什么呢?
因为lower_bound输出的是第一个大于等于要查找的元素值的位置 但是如果最小值出在比它小的呢?这时候就没有“super_lower_bound",只能对返回值进行特判。
所以首先要设一个p2,用来存比p1小的值,再来个d1和d2,用来存两者和x的差,最后来比较两者谁小,最后来输出p1或p2所对应的值。这里又有一个错点:直接输出p1或p2,注意⚠️:我们题要的是值,而非位置!!
成体代码如下:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int num[100005];
int main() {
freopen("closest.in", "r", stdin);
freopen("closest.out", "w", stdout);
int n, m, x;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> num[i];
}
cin >> m;
int p1,p2,d1,d2;
while (m--) {
cin >> x;
p1 = lower_bound(num, num + n, x) - num;
p2 = p1 - 1;
d1 = 2000000000;
d2 = 2000000000;
if(p1 != n)
{
d1 = num[p1] - x;
}
if(p2 != -1)
{
d2 = x - num[p2];
}
if(d1 < d2)
{
cout << num[p1] << endl;
}
else
{
cout << num[p2] << endl;
}
}
return 0;
}
最后再来总结一下思路:
- 读入
- 用lower_bound求出p1
- 设好p2,d1,d2
- 求出d1,d2
- 比较
- 输出
所以遇到这种题一定要注意,用了lower_bound或upper_bound之后要注意有没有特殊情况需要特判,才能提高正确率。
祝各位学业进步,马到成功!
本文探讨了在非降序序列中查找最接近指定值x的元素的算法问题。通过计蒜客的在线课程示例,指出仅使用`lower_bound`可能会导致错误,并解释了错误的原因。解决方案是结合`lower_bound`的结果进行特判,存储并比较差值,以确定实际最接近的元素。最后强调,在处理这类问题时,需要注意特殊情况的特判以确保正确性。
1418

被折叠的 条评论
为什么被折叠?



