本文主要是介绍华为杯“华南理工大学程序设计竞赛(同步赛) A KNN算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目:华为杯“华南理工大学程序设计竞赛(同步赛) A KNN算法
参考:“华为杯“华南理工大学程序设计竞赛(同步赛)题解A——二分的深入理解
思路
思路挺好想的,二分枚举答案,判断距离为mid时是否满足范围内刚好有k个点
但是赛场了调了很久…果然我不会二分
注意点
1.lower_bound和upper_bound:
lower_bound返回的是第一个大于等于目标值的迭代器。
upper_bound返回的是第一个大于目标值的迭代器。
如果目标值在序列中有多个,lower_bound返回的是第一个目标值的迭代器,而upper_bound返回的是最后一个目标值的下一个迭代器。
现在我们要求所有坐标落在[x-mid, x+mid]
范围内的点的个数
lc
表示第一个坐标大于等于x-mid
的点的下标
rc
表示第一个坐标大于x+mid
的点的下标(也就是最后一个坐标小于等于x+mid
的点的下标(设为rct)+1)
那么rc-lc
就是所求
(其实所有满足条件的点下标在[lc, rtc]之间,个数就是rct - lc + 1
,也就是rc - lc
)
2.l和r的初值
l和r的初值其实就是答案的可能取值,由于坐标范围是[-1e9, 1e9]
,所以答案的取值是[0, 2e9]
,l取0,r取2e9
3.开long long
在二分过程中l和r的取值范围是[0, 2e9]
,l+r是会爆int的,所以l、r、mid都要开long long
因为这个wa了好多好多发…甚至过几天重新来理才反应过来
代码
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;typedef long long ll;
const int N = 2e5 + 5;int a[N];int main()
{int n, q;cin >> n >> q;for (int i = 0; i < n; i++)cin >> a[i];sort(a, a + n);while (q--){int x, k;cin >> x >> k;ll l = 0, r = 2e9;while (l < r){ll mid = l + r >> 1;int lc = lower_bound(a, a + n, x - mid) - a;int rc = upper_bound(a, a + n, x + mid) - a;if (rc - lc >= k)r = mid;else l = mid + 1;} cout << l << endl;}return 0;
}
这篇关于华为杯“华南理工大学程序设计竞赛(同步赛) A KNN算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!