51Nod拉勾专业算法能力测评

来源:互联网 发布:c 编程培训中心 编辑:程序博客网 时间:2024/05/19 06:15
                      **走格子**

基准时间限制:1 秒 空间限制:131072 KB 分值: 5
有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格子走出去。机器人有一个初始能量,每个格子对应一个整数A[i],表示这个格子的能量值。如果A[i] > 0,机器人走到这个格子能够获取A[i]个能量,如果A[i] < 0,走到这个格子需要消耗相应的能量,如果机器人的能量 < 0,就无法继续前进了。问机器人最少需要有多少初始能量,才能完成整个旅程。

例如:n = 5。{1,-2,-1,3,4} 最少需要2个初始能量,才能从1号走到5号格子。途中的能量变化如下3 1 0 3 7。
Input
第1行:1个数n,表示格子的数量。(1 <= n <= 50000)
第2 - n + 1行:每行1个数A[i],表示格子里的能量值(-1000000000 <= A[i] <= 1000000000)
Output
输出1个数,对应从1走到n最少需要多少初始能量。
Input示例
5
1
-2
-1
3
4
Output示例
2

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int main(){    long long int m,n,s=0,i;    long long int minn=0x3f3f3f3f;    scanf("%lld",&n);    for(i=0;i<n;i++)    {        scanf("%lld",&m);        s+=m;        if(s<minn)            minn=s;    }    if(minn>=0)        printf("0\n");    else        printf("%lld\n",0-minn);    return 0;}
                      **扔盘子**

基准时间限制:1 秒 空间限制:131072 KB 分值: 10
有一口井,井的高度为N,每隔1个单位它的宽度有变化。现在从井口往下面扔圆盘,如果圆盘的宽度大于井在某个高度的宽度,则圆盘被卡住(恰好等于的话会下去)。
盘子有几种命运:1、掉到井底。2、被卡住。3、落到别的盘子上方。
盘子的高度也是单位高度。给定井的宽度和每个盘子的宽度,求最终落到井内的盘子数量。

如图井和盘子信息如下:
井:5 6 4 3 6 2 3
盘子:2 3 5 2 4

最终有4个盘子落在井内。
本题由 @javaman 翻译。
Input
第1行:2个数N, M中间用空格分隔,N为井的深度,M为盘子的数量(1 <= N, M <= 50000)。
第2 - N + 1行,每行1个数,对应井的宽度Wi(1 <= Wi <= 10^9)。
第N + 2 - N + M + 1行,每行1个数,对应盘子的宽度Di(1 <= Di <= 10^9)
Output
输出最终落到井内的盘子数量。
Input示例
7 5
5
6
4
3
6
2
3
2
3
5
2
4
Output示例
4
这个题目正着来做肯定比较麻烦,可以试着简化一下

#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int main(){    int n,m;    int i,j;    int a[50005],b[50005];    scanf("%d %d",&n,&m);    for(i=0;i<n;i++)       scanf("%d",&a[i]);    for(i=0;i<m;i++)       scanf("%d",&b[i]);    for(i=1;i<n;i++)       a[i]=min(a[i-1],a[i]);//从井口向下进行初始化,只有上面的横截面积比下面的横截面积大才有意义    int count=0;    for(i=0;i<m;i++)    {        for(n--;n>=0;n--)//当前盘子可以卡住的话数目加1,继续判断下一个盘子情况        {            if(a[n]>=b[i])              break;        }        if(n>=0)            count++;    }    printf("%d\n",count);    return 0;}
                    **独木舟**

基准时间限制:1 秒 空间限制:131072 KB 分值: 10
n个人,已知每个人体重。独木舟承重固定,每只独木舟最多坐两个人,可以坐一个人或者两个人。显然要求总重量不超过独木舟承重,假设每个人体重也不超过独木舟承重,问最少需要几只独木舟?
Input
第一行包含两个正整数n (0

首先将人的体重升序排列,再从两头一起开始判断#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int main(){    int n,m;    int a[10005],b[10005],i,j;    memset(b,0,sizeof(b));    scanf("%d %d",&n,&m);    int k=n-1,sum=0;    for(i=0;i<n;i++)        scanf("%d",&a[i]);    sort(a,a+n);    for(i=0;i<=k;i++)    {        int flag=0;        if(b[i]==0)        {            for(j=k;j>=i;j--)                if(b[j]==0&&a[i]+a[j]<=m)            {                sum++;                b[i]=1;                b[j]=1;                flag=1;                //k=j-1;                break;            }            if(flag==0)            {                b[i]=1;                sum++;            }        }    }    printf("%d\n",sum);    return 0;}
                    **斜率最大** 

基准时间限制:1 秒 空间限制:131072 KB 分值: 20
平面上有N个点,任意2个点确定一条直线,求出所有这些直线中,斜率最大的那条直线所通过的两个点。
(点的编号为1-N,如果有多条直线斜率相等,则输出所有结果,按照点的X轴坐标排序,正序输出。数据中所有点的X轴坐标均不相等,且点坐标为随机。)
Input
第1行,一个数N,N为点的数量。(2 <= N <= 10000)
第2 - N + 1行:具体N个点的坐标,X Y均为整数(-10^9 <= X,Y <= 10^9)
Output
每行2个数,中间用空格分隔。分别是起点编号和终点编号(起点的X轴坐标 < 终点的X轴坐标)
Input示例
5
1 2
6 8
4 4
5 4
2 3
Output示例
4 2
刚开始是用常规方法做,当然时间超了
后来才知道可以用数学结论节省时间
先把这些点按x坐标从小到大排序,斜率最大的两点必然是挨一起的两个点,所以排序O(n* lg n),遍历一次O(n)就够了
详细解释看这里

#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct node{    int x;    int y;    int z;    double d;};int cmp(node a,node b){    a.x<b.x;}int main(){    int n;    int i,j;    double t;    node a[10005],d;    scanf("%d",&n);    for(i=0;i<n;i++)    {        scanf("%d %d",&a[i].x,&a[i].y);        a[i].z=i;    }    for(i=0;i<n-1;i++)        for(j=i+1;j<n;j++)    {        if(a[i].x>a[j].x)        {            d.x=a[i].x;            d.y=a[i].y;            d.z=a[i].z;            a[i].x=a[j].x;            a[i].y=a[j].y;            a[i].z=a[j].z;            a[j].x=d.x;            a[j].y=d.y;            a[j].z=d.z;        }    }    double maxn=-0x3f3f3f3f;    for(i=0;i<n-1;i++)    {        if(a[i].x!=a[i+1].x)        {            double t=(a[i+1].y-a[i].y)*1.0/(a[i+1].x-a[i].x);            a[i].d=t;            if(maxn<t)               maxn=t;        }    }    for(i=0;i<n-1;i++)    {        if(maxn==a[i].d)        {            printf("%d %d\n",a[i].z+1,a[i+1].z+1);        }    }    return 0;}

数据流中的算法
基准时间限制:1.5 秒 空间限制:131072 KB 分值: 20
51nod近日上线了用户满意度检测工具,使用高级人工智能算法,通过用户访问时间、鼠标轨迹等特征计算用户对于网站的满意程度。

现有的统计工具只能统计某一个窗口中,用户的满意程度的均值。夹克老爷想让你为统计工具添加一个新feature,即在统计均值的同时,计算窗口中满意程度的标准差和中位数(均值需要向下取整)。
Input
第一行是整数n与k,代表有n次操作,时间窗口大小为k。
(1 <= n <= 10^6, 1 <= k <= 100)

接下来的n行,每行代表一次操作。操作有“用户访问”、“查询均值”、“查询方差”、“查询中位数”四种。每行的第一个数代表操作类型。

操作数1:用户访问
输入格式:<1, v>
用户的满意度v为闭区间[0, 100]中的任意整数。用户每访问一次,数据更新,移动统计窗口。

操作数2:查询均值
输入格式:<2>
统计窗口内的用户满意度的均值。

操作数3:查询方差
输入格式:<3>
统计窗口内用户满意度的方差

操作数4:查询中位数
输入格式:<4>
统计窗口内用户满意度的中位数

p.s. 在有查询请求时,窗口保证不为空
p.s.s. 有查询请求时,窗口可能不满
Output
对于“查询均值”、“查询方差”、“查询中位数”操作的结果,输出保留两位小数。
Input示例
12 3
1 1
1 2
1 3
2
3
4
1 4
1 5
1 6
2
3
4
Output示例
2.00
0.67
2.00
5.00
0.67
5.00
k的用处题目描述的不清楚,可以理解为该统计工具所能保存的数据个数
比较复杂的一道模拟题
特别是求中位数时容易超时,由于满意度的取值范围不大,用户的满意度v为闭区间[0, 100]中的任意整数,所以可用一个稍大于100数组来存放用户的满意度,就可避免超时

#include<stdio.h>#include<string.h>int main(){    int n,k,now;    int i,j,a[105],ss[105];    scanf("%d %d",&n,&k);    for(i=0;i<k;i++)        a[i]=-1;    char s[10];    int ii=-1;    getchar();    now=0;    for(i=0;i<=100;i++)        ss[i]=0;    for(int iii=0;iii<n;iii++)    {        //printf("iii:%d\n",iii);        gets(s);        int t=0;        if(s[0]=='1')        {            int len=strlen(s);            for(i=2;i<len;i++)            if(s[i]>='0'&&s[i]<='9')            t=t*10+s[i]-'0';            ii++;            ss[a[ii%k]]--;            a[ii%k]=t;            ss[a[ii%k]]++;            if(ii<k)            now++;        }        else if(s[0]=='2')        {            int sum=0;            int tt=0;            for(i=0;i<k;i++)            {                if(a[i]!=-1)                {                    tt++;                    sum+=a[i];                }            }            if(tt!=0)            {                int su=sum/tt;                sum=su;                printf("%d.00\n",su);            }        }        else if(s[0]=='3')        {            double sum=0,s=0;            int tt=0;            for(int i=0;i<k;i++)            {                if(a[i]!=-1)                {                    tt++;                    sum+=a[i];                }            }            if(tt!=0)            sum=sum*1.0/tt;            for(int i=0;i<k;i++)            {                if(a[i]!=-1)                 s+=(a[i]-sum)*(a[i]-sum);            }            s=s/tt;            printf("%.2lf\n",s);        }        else if(s[0]=='4')        {            int flag=0,tlag;            int ttt;            if(now%2!=0)            {                ttt=-1;                for(int kk=0;kk<=100;kk++)                {                    if(flag==0)                    {                        ttt+=ss[kk];//printf("ttt:%d\n",ttt);                        if(ttt>=now/2)                        {                            printf("%.2lf\n",(double)kk);                            flag=1;                        }                    }                }            }            else            {                int st,ed;                int rlag=0;                tlag=0,flag=0;                ttt=-1;                for(int kk=0;kk<=100;kk++)                {                    //printf("ss[%d]:%d\n",kk,ss[kk]);                    if(tlag==0||flag==0)                    {                        ttt+=ss[kk];//printf("ttt:%d\n",ttt);                        if(ttt>=now/2-1&&tlag==0)                        {                            st=kk;                            tlag=1;                        }                        if(ttt>=now/2&&flag==0)                        {                            ed=kk;                            flag=1;                        }                    }                    if(tlag==1&&flag==1&&rlag==0)                    {                        printf("%.2lf\n",(double)(st+ed)/2);                        rlag=1;                    }                }            }        }    }    return 0;}