思路:二分查找;
对于每一个学生,找到第一个小于等于他分数的学校分数,再找到第一个大于等于他分数的学校分数,比较一下前者与他分数之差和后者与他分数之差,取小的那个,加到答案里面去。
可以使用STL里的lower_bound()来做这道题,lower_bound()找到升序数组中第一个大于等于所求数的位置,利用重载lower_bound(v.begin(),v.end(),x,greater<int>())找到降序数组中第一个小于等于所求数的位置,对应这道题,就是用lower_bound()在升序数组中找到第一个大于等于他分数的学校分数,再用重载lower_bound(v.begin(),v.end(),x,greater<int>())找到降序数组中第一个小于等于他分数的学校分数,比较一下前者与他分数之差和后者与他分数之差,取小的那个,加到答案里面去。
注意:如果用重载lower_bound(v.begin(),v.end(),x,greater<int>())找不到降序数组中第一个小于等于他分数的学校分数,那么只有用这个学生的分数减去最低学校的分数,加到答案里面去即可。
使用long long解决这个问题。
#include<bits/stdc++.h>
#define endl "\n";
using namespace std;
typedef long long ll;
const int N=1e6+5;
typedef pair<int,int> PII;
const int INF=0x3f3f3f3f;
typedef struct node{
}node;
void IOS(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
}
//试试upper_bound(),lower_bound();
ll n,m;
void solve(){
cin>>m>>n;
ll cnt=0;
vector<ll>vec(m),v(n);
for(int i=0;i<m;++i){
cin>>vec[i];
}
sort(vec.begin(),vec.end());
auto vec2=vec;
reverse(vec2.begin(),vec2.end());
for(int i=0;i<n;++i){
cin>>v[i];
if(v[i]<vec[0]){
cnt+=vec[0]-v[i];
}
else{
ll kk1=lower_bound(vec2.begin(),vec2.end(),v[i],greater<int>())-vec2.begin();
ll kk2=lower_bound(vec.begin(),vec.end(),v[i])-vec.begin();
cnt+=min(abs(vec2[kk1]-v[i]),abs(vec[kk2]-v[i]));
}
}
cout<<cnt;
}
int main(){
IOS();
solve();
return 0;
}
文章讲述了如何运用C++中的二分查找算法(lower_bound)来解决一个问题:对于每个学生,找到与其分数最接近的学校分数线,计算差距并累加最小差距。涉及到升序和降序数组的操作以及longlong类型来存储大整数。
651

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



