P1678 烦恼的高考志愿 (暴力,二分+排序)

思路:先用暴力方法求解。

采用二分,结合排序,找最接近学生分数的两个分数。

少了一个特判情况,当考生的分数比最低的分数线都要低时,直接在答案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;
} 

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值