网易编程题解析(二)

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
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct score_hour
{
    int score;
    int hour;
};
bool cmp(score_hour a,score_hour b)
{
    return a.hour<b.hour;
}
int main()
{
    int n,r,avg;
    while(cin>>n>>r>>avg)
    {
        int target=avg*n;
        long time=0;
        vector<score_hour> table(n);
        for(int i=0;i<n;i++)
        {
            cin>>table[i].score;
            cin>>table[i].hour;
            target=target-table[i].score;
        }
        if(target<=0)
        {
            cout<<0<<endl;
        }
        else
        {
            sort(table.begin(),table.end(),cmp);
            for(int i=0;i<n;i++)
            {
                if(target<=r-table[i].score)
                {
                    time=time+target*table[i].hour;
                    break;
                }
                else
                {
                    target=target-(r-table[i].score);
                    time=time+(r-table[i].score)*table[i].hour;
                }
            }
            cout<<time<<endl;
        }
    }
    return 0;
}
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.50
先对路灯坐标进行排序,然后求相邻路灯之间的最大间隔。需注意边界情况:边界的射程是len1的话,那么中间最大差值是len2,应该是用len2/2和len1比较,d为最大值。
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
using namespace std;
int main()
{
    int n,l;
    while(cin>>n>>l)
    {
        vector<int> table(n);
        for(int i=0;i<n;i++)
            cin>>table[i];
        sort(table.begin(),table.end());
        double max_dis=table[1]-table[0];
        for(int i=2;i<n;i++)
        {
            if(table[i]-table[i-1]>max_dis)
                max_dis=table[i]-table[i-1];
        }
        if(2*(table[0]-0)>max_dis)
        {
             max_dis=(table[0]-0)*2;
        }
        if((l-table[n-1])*2>max_dis)
        {
            max_dis=(l-table[n-1])*2;
        }
         printf("%.2f\n",max_dis/2.0);
    }
    return 0;
}
3、小易的升级之路
小易经常沉迷于网络游戏.有一次,他在玩一个打怪升级的游戏,他的角色的初始能力值为 a.在接下来的一段时间内,他将会依次遇见n个怪物,每个怪物的防御力为b1,b2,b3...bn. 如果遇到的怪物防御力bi小于等于小易的当前能力值c,那么他就能轻松打败怪物,并 且使得自己的能力值增加bi;如果bi大于c,那他也能打败怪物,但他的能力值只能增加bi 与c的最大公约数.那么问题来了,在一系列的锻炼后,小易的最终能力值为多少?
输入描述:
对于每组数据,第一行是两个整数n(1≤n<100000)表示怪物的数量和a表示小易的初始能力值.第二行n个整数,b1,b2...bn(1≤bi≤n)表示每个怪物的防御力
输出描述:
对于每组数据,输出一行.每行仅包含一个整数,表示小易的最终能力值
输入
3 5050 105 2005 2030 20 15 40 100
输出
110
205
#include<iostream>
#include<vector>
using namespace std;
int measure(int x,int y)
{
    int z=y;
    while(x%y!=0)
    {
        z=x%y;
        x=y;
        y=z;
    }
    return z;
}
int main()
{
    int n,a;
    while(cin>>n>>a)
    {
        vector<int> b(n);
        int c=a;
        for(int i=0;i<n;i++)
            cin>>b[i];
        for(int i=0;i<n;i++)
        {
            if(b[i]<=c)
                c=c+b[i];
            else
            {
                c=c+measure(b[i],c);
            }
        }
        cout<<c<<endl;
    }
}
4、炮台攻击
兰博教训提莫之后,然后和提莫讨论起约德尔人,谈起约德尔人,自然少不了一个人,那 就是黑默丁格------约德尔人历史上最伟大的科学家. 提莫说,黑默丁格最近在思考一个问题:黑默丁格有三个炮台,炮台能攻击到距离它R的敌人 (两点之间的距离为两点连续的距离,例如(3,0),(0,4)之间的距离是5),如果一个炮台能攻击 到敌人,那么就会对敌人造成1×的伤害.黑默丁格将三个炮台放在N*M方格中的点上,并且给出敌人 的坐标. 问:那么敌人受到伤害会是多大?
输入描述:
第一行9个整数,R,x1,y1,x2,y2,x3,y3,x0,y0.R代表炮台攻击的最大距离,(x1,y1),(x2,y2), (x3,y3)代表三个炮台的坐标.(x0,y0)代表敌人的坐标.
输出描述:
输出一行,这一行代表敌人承受的最大伤害,(如果每个炮台都不能攻击到敌人,输出0×)
输入
1 1 1 2 2 3 3 1 2
输出
2x
#include<iostream>
#include<math.h>
using namespace std;
int distance(int a,int b,int c,int d)
{
    return sqrt((a-c)*(a-c)+(b-d)*(b-d));
}
int main()
{
    int r,x1,y1,x2,y2,x3,y3,x0,y0;
    while(cin>>r>>x1>>y1>>x2>>y2>>x3>>y3>>x0>>y0)
    {
        int num=0;
        if(distance(x1,y1,x0,y0)<r)
        {
            num++;
        }
        if(distance(x2,y2,x0,y0)<r)
        {
            num++;
        }
        if(distance(x3,y3,x0,y0)<r)
        {
            num++;
        }
        cout<<num<<"x"<<endl;
    }
    return 0;
}
5、扫描透镜
在N*M的草地上,提莫种了K个蘑菇,蘑菇爆炸的威力极大,兰博不想贸然去闯,而且蘑菇是隐形的.只 有一种叫做扫描透镜的物品可以扫描出隐形的蘑菇,于是他回了一趟战争学院,买了2个扫描透镜,一个 扫描透镜可以扫描出(3*3)方格中所有的蘑菇,然后兰博就可以清理掉一些隐形的蘑菇. 问:兰博最多可以清理多少个蘑菇?
注意:每个方格被扫描一次只能清除掉一个蘑菇。
输入描述:
第一行三个整数:N,M,K,(1≤N,M≤20,K≤100),N,M代表了草地的大小;接下来K行,每行两个整数x,y(1≤x≤N,1≤y≤M).代表(x,y)处提莫种了一个蘑菇.一个方格可以种无穷个蘑菇.
输出描述:
输出一行,在这一行输出一个整数,代表兰博最多可以清理多少个蘑菇.
一个扫描透镜可以扫描出(3*3)方格中的所有蘑菇,问最多可清理多少个蘑菇就是求二维数组中哪一块(3*3)区域中的蘑菇数最多。有两个透镜,那么最多可清理的蘑菇数就是第一个透镜最多清理的加上第二个透镜最多清理的(将求最多清理蘑菇数写成函数)。需要注意的是对于每个方格如果其中有多个蘑菇那么一次扫描只能清理掉一个蘑菇。这要求我们在求出第一个最优解后要对二维数组中的相应方格中的蘑菇数进行减1操作。
#include<iostream>
#include<vector>
using namespace std;
void scan(vector<vector<int> >fields,int n,int m,int result[])
{
    for(int i=0;i<n-2;i++)
    {
        for(int j=0;j<m-2;j++)
        {
            int tmp=0;
            for(int p=i;p<i+3;p++)
            {
                for(int q=j;q<j+3;q++)
                {
                    if(fields[p][q]>0)
                        tmp++;
                }
            }
            if(result[0]<tmp)
            {
                result[0]=tmp;
                result[1]=i;
                result[2]=j;
            }
        }
    }
}
int main()
{
    int n,m,k;
    while(cin>>n>>m>>k)
    {
        if(n<3)
            n=3;
        if(m<3)
            m=3;
        vector<vector<int> > fields(n,vector<int>(m,0));
        while(k--)
        {
            int x,y;
            cin>>x>>y;
            fields[x-1][y-1]++;
        }
        int first[3]={0};
        int second[3]={0};
        scan(fields,n,m,first);
        for(int i=first[1];i<first[1]+3;i++)
        {
            for(int j=first[2];j<first[2]+3;j++)
                fields[i][j]--;
        }
        scan(fields,n,m,second);
        cout<<first[0]+second[0]<<endl;
    }
    return 0;
}












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值