思路:先用暴力方法求解。
采用二分,结合排序,找最接近学生分数的两个分数。
少了一个特判情况,当考生的分数比最低的分数线都要低时,直接在答案cnt上加(fen【0】 - stu【i】),其他情况在比较分数线在考生分数左右的差值最小。
//因为最左端的时候可能是数组访问越界,还有就是距离0很近,需要特判!!!!

代码1:TLE了
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
int n,m;
int fen[100010];
int stu[100010];
int cnt;
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&fen[i]);
}
for(int i=0;i<m;i++){
scanf("%d",&stu[i]);
}
//先用暴力
for(int i=0;i<m;i++){//根据每个学生推荐
int minn = 10000000;
for(int j=0;j<n;j++){
if(abs(stu[i] - fen[j]) < minn) minn = abs(stu[i] - fen[j]);
}
cnt += minn;
}
printf("%d",cnt);
return 0;
}
结果:

代码2:哦不!!我的龙龙!!50分
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
int n,m;
int fen[100100];
int stu[100100];
long long cnt;
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&fen[i]);
}
for(int i=0;i<m;i++){
scanf("%d",&stu[i]);
}
//先用暴力
for(int i=0;i<m;i++){//根据每个学生推荐
int minn = 10000000;
for(int j=0;j<n;j++){
if(abs(stu[i] - fen[j]) < minn) minn = abs(stu[i] - fen[j]);
}
cnt += minn;
}
printf("%lld",cnt);
return 0;
}
结果:

排序+二分代码:70分
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
int n,m;
int fen[100100];
int stu[100100];
long long cnt;
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&fen[i]);
}
for(int i=0;i<m;i++){
scanf("%d",&stu[i]);
}
//排序加二分
sort(fen,fen+n);
for(int i=0;i<m;i++){//根据每个学生推荐
int l = 0,r = n;//二分学校分数线下标
while(l < r){
//找左端点
int mid = l + r >> 1;//左端大右
if(fen[mid] >= stu[i]) r = mid;
else l = mid+1;
}
int x1 = abs(fen[l] - stu[i]);
int x2 = abs(fen[l-1] - stu[i]);
// printf("&&&&&%d x1:%d x2:%d\n",fen[l],x1,x2);
if(x1 < x2) cnt += x1;
else cnt += x2;
}
printf("%lld",cnt);
return 0;
}
结果:

AC代码:少了一个特判情况,当考生的分数比最低的分数线都要低时,直接在答案cnt上加(fen【0】 - stu【i】),其他情况在比较分数线在考生分数左右的差值最小。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
long long int n,m;
long long int fen[100100];
long long int stu[100100];
long long int cnt;
int main()
{
scanf("%lld%lld",&n,&m);
for(int i=0;i<n;i++){
scanf("%lld",&fen[i]);
}
for(int i=0;i<m;i++){
scanf("%lld",&stu[i]);
}
sort(fen,fen+n);
//先用暴力
for(int i=0;i<m;i++){//根据每个学生推荐
int minn = 10000000;
int l = 0,r = n - 1;//二分学校分数线下标
while(l < r){
//找左端点
int mid = l + r >> 1;//左端大右
if(fen[mid] <= stu[i]) l = mid + 1;
else r = mid;
}
if(stu[i] < fen[0]){
cnt += fen[0] - stu[i];
}
else{
int x1 = abs(fen[l] - stu[i]);
int x2 = abs(fen[l-1] - stu[i]);
// int x3 = abs(fen[l+1] - stu[i]);
// printf("&&&&&%d x1:%d x2:%d\n",fen[l],x1,x2);
minn = min(x1,x2);
// minn = min(minn,x3);
cnt += minn;
}
}
printf("%lld",cnt);
return 0;
}
结果:
