网易2016游戏技术岗在线编程题(二)

题目来源:牛客网-网易2016年研发工程师编程题二

1. 奖学金

小v今年有n门课,每门都有考试,为了拿到奖学金,小v必须让自己的平均成绩至少为avg。每门课由平时成绩和考试成绩组成,满分为r。现在他知道每门课的平时成绩为ai ,若想让这门课的考试成绩多拿一分的话,小v要花bi 的时间复习,不复习的话当然就是0分。同时我们显然可以发现复习得再多也不会拿到超过满分的分数。为了拿到奖学金,小v至少要花多少时间复习。

输入描述:
第一行三个整数n,r,avg(n大于等于1小于等于1e5,r大于等于1小于等于1e9,avg大于等于1小于等于1e6),接下来n行,每行两个整数ai和bi,均小于等于1e6大于等于1

输出描述:
一行输出答案。

输入例子:

5 10 9
0 5
9 1
8 1
0 1
9 100

输出例子:

43

分析:
完成这个题目需要注意两个问题:
(1)求出最少复习时间,需要优先选择每分的复习时间最小的课程,那么需要对<平时成绩,复习时间>元素对按复习时间递增进行排序;
(2)因为课程数很多,每分复习时间很大,所需最小复习时间需要长整型来存储,以防溢出;
(3)如果所需复习时间小于等于0,需要特殊处理。

测试通过源码:

#include  <iostream>
#include <vector>
#include <algorithm>
using namespace std;


bool compare(const vector<int>& vec0,const vector<int>& vec1) {
  return vec0[1]<vec1[1]; //升序排列
}

int main(int argc,char* argv[]) {
	int courseNum=0,maxScore=0,average=0;
	while(cin>>courseNum>>maxScore>>average) {
		vector<vector<int> > regularGrade_effort(courseNum,vector<int>(2,0));
		int regularGradeSum=0;//平时总分
		for(int i=0;i<courseNum;++i) {
			cin>>regularGrade_effort[i][0]>>regularGrade_effort[i][1];
			regularGradeSum+=regularGrade_effort[i][0];
		}
		sort(regularGrade_effort.begin(),regularGrade_effort.end(),compare);//按每分的复习时间升序排列
		
        long long int minimumTime=0;  //因为每分的复习时间很大,需要长整型,否则溢出,不能通过测试
		int needScore=courseNum*average-regularGradeSum;
        if (needScore <=0)    
        	goto end;  
		
		for(int i=0;i<courseNum;++i) {
			for(int j=0;j<maxScore-regularGrade_effort[i][0];++j) {
				--needScore;
				minimumTime+=regularGrade_effort[i][1];
				if(needScore==0)
				    goto end;
			}
		}
		end:
			cout<<minimumTime<<endl;
	}
}

2.路灯

一条长l的笔直的街道上有n个路灯,若这条街的起点为0,终点为l,第i个路灯坐标为ai,每盏灯可以覆盖到的最远距离为d,为了照明需求,所有灯的灯光必须覆盖整条街,但是为了省电,要求这个d最小,请找到这个最小的d。

输入描述:
每组数据第一行两个整数n和l(n大于0小于等于1000,l小于等于1000000000大于0)。第二行有n个整数(均大于等于0小于等于l),为每盏灯的坐标,多个路灯可以在同一点。

输出描述:
输出答案,保留两位小数。

输入例子:

7 15
15 5 3 7 9 14 0

输出例子:

2.5

分析:
(1)问题的实质是求一个数组序列中的两个连续元素之间的最大差值,还需要考虑首尾的特殊性;
(2)我为了练习set集合容器,所以使用了set来存储路灯位置,当然你也可以使用vector容器。相对于vector容器,其好处是元素不重复,自动排序,劣势就是迭代器不支持算术加减操作,只支持自增++和自减–操作。

测试通过的源码:

#include  <iostream>
#include <set>
#include <iomanip>
using namespace std;

int main(int argc,char* argv[]) {
	int n=0,l=0;
	set<int> lampPos;  //默认升序排列
	while(cin>>n>>l){
		int pos=0;
		for(int i=0;i<n;++i){
			cin>>pos;
			lampPos.insert(pos);
		}
		int maxDistance=0;
		for(set<int>::iterator it=lampPos.begin();it!=--lampPos.end();++it){
			set<int>::iterator nextIt=++it;
			--it;
			if((*nextIt-*it)>maxDistance)
				maxDistance=*nextIt-*it;
		}
		float d=(float)maxDistance/2;
		//考虑第一个路灯到路的开始位置
		if(*lampPos.begin()>d)
			d=*lampPos.begin();
		//考虑最后一个路灯到路的结束
		if(l-*(--lampPos.end())>d)
			d=l-*(--lampPos.end());
		lampPos.clear();	
		cout<<setiosflags(ios::fixed)<<setprecision(2)<<d<<endl;
	}
}

参考文献

[1] 另一位网友实现.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值