百度2016研发工程师在线编程题

来源:互联网 发布:传奇刷装备软件 编辑:程序博客网 时间:2024/06/11 02:43

题目链接:http://www.nowcoder.com/test/question/analytic?tid=1667855


[编程题]罪犯转移
C市现在要转移一批罪犯到D市,C市有n名罪犯,按照入狱时间有顺序,另外每个罪犯有一个罪行值,值越大罪越重。现在为了方便管理,市长决定转移入狱时间连续的c名犯人,同时要求转移犯人的罪行值之和不超过t,问有多少种选择的方式? 

输入描述:
第一行数据三个整数:n,t,c(1≤n≤2e5,0≤t≤1e9,1≤c≤n),第二行按入狱时间给出每个犯人的罪行值ai(0≤ai≤1e9)


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

输入例子:
3 100 21 2 3

输出例子:
2
题意:求区间长度为c的连续序列的和小于等于t的区间的个数!

思路:我用两个变量来控制区间的大小,先向前扩展到c的长度,然后左区间向右移动,寻找下一个符合条件的区间;sum用来记录区间和,O(n)

#include<stdio.h>int num[200005];int main(){    int n,t,c;    while(scanf("%d%d%d",&n,&t,&c)!=EOF)    {        for(int i=0;i<n;i++)        {            scanf("%d",&num[i]);        }        if(c==0){printf("0\n");continue;}        int cnt=0;        int sum=0;        int i=0,j=0;        for(;i<n&&j<n;j++)        {            if(num[j]>t) {sum=0;i=j+1;}            if(j-i+1<c) {sum+=num[j];continue;}            if(j-i+1>c) {sum-=num[i++];}            if(j-i+1==c)            {                sum+=num[j];                if(sum<=t)                    cnt++;                else if(sum>t)                {                    while(sum>t)                    {                        sum-=num[i++];                    }                }            }        }        printf("%d\n",cnt);    }    return 0;}


[编程题]裁减网格纸
度度熊有一张网格纸,但是纸上有一些点过的点,每个点都在网格点上,若把网格看成一个坐标轴平行于网格线的坐标系的话,每个点可以用一对整数x,y来表示。度度熊必须沿着网格线画一个正方形,使所有点在正方形的内部或者边界。然后把这个正方形剪下来。问剪掉正方形的最小面积是多少。 
输入描述:
第一行一个数n(2≤n≤1000)表示点数,接下来每行一对整数xi,yi(-1e9<=xi,yi<=1e9)表示网格上的点


输出描述:
一行输出最小面积

输入例子:
20 00 3

输出例子:
9
题意:求包围点的最小正方形面积,且正方形必须沿着网格剪,so。。。本来以为是凸包的,但认真看清题意,原来只是个水题,贪心就可以了。找到最大和最小的x,y,求最大的边长,即可求最小的面积。

//由于必须要沿着网格线剪下,即必须到x、y轴//so 只有要找最大最小的x,y即可#include<stdio.h>#include<algorithm>using namespace std;struct point{    int x;    int y;}po[1005];int main(){    int n;    while(~scanf("%d",&n))    {        for(int i=0;i<n;i++)        {            scanf("%d%d",&po[i].x,&po[i].y);        }        int maxx=po[0].x;        int minx=po[0].x;        int maxy=po[0].y;        int miny=po[0].y;        for(int i=1;i<n;i++)        {            maxx=max(maxx,po[i].x);            minx=min(minx,po[i].x);            maxy=max(maxy,po[i].y);            miny=min(miny,po[i].y);        }        int div=max(maxx-minx,maxy-miny);        printf("%d\n",div*div);    }    return 0;}


[编程题]钓鱼比赛
ss请cc来家里钓鱼,鱼塘可划分为n*m的格子,每个格子每分钟有不同的概率钓上鱼,cc一直在坐标(x,y)的格子钓鱼,而ss每分钟随机钓一个格子。问t分钟后他们谁至少钓到一条鱼的概率大?为多少?

输入描述:
第一行五个整数n,m,x,y,t(1≤n,m,t≤1000,1≤x≤n,1≤y≤m);接下来为一个n*m的矩阵,每行m个一位小数,共n行,第i行第j个数代表坐标为(i,j)的格子钓到鱼的概率为p(0≤p≤1)


输出描述:
输出两行。第一行为概率大的人的名字(cc/ss/equal),第二行为这个概率(保留2位小数)

输入例子:
2 2 1 1 10.2 0.10.1 0.4

输出例子:
equal0.20
题意:略

思路:简单的概率题,首先求<<至少钓到一条鱼的概率=1-一条都钓不到的概率;>>那么现在来求各自钓不到的鱼的概率,cc一直不动,所以很简单,那么ss每次都是随机选择,所以我们要求他的数学期望,在一次选择中不能钓到鱼的概率为1-(每个格子钓到鱼的概率的和 / 总格子数) ;由于是要比较t次,在概率中表示为pow(),最后1-不能的=能的;


#include<stdio.h>#include<math.h>int main(){    int n,m,x,y,t;    while(scanf("%d%d%d%d%d",&n,&m,&x,&y,&t)!=EOF)    {        double cc=0.0,ss=0.0;        double tmp;        for(int i=1; i<=n; i++)        {            for(int j=1; j<=m; j++)            {                scanf("%lf",&tmp);                if(i==x&&j==y) cc=1-tmp;                ss+=tmp;            }        }        ss=1-ss/(n*m);        cc=1-pow(cc,t);        ss=1-pow(ss,t); //               printf("%f\t%f\n",ss,cc);        if(cc==ss)        {            printf("equal\n%.2f\n",cc);        }        else if(ss>cc)        {            printf("ss\n%.2f\n",ss);        }        else        {             printf("cc\n%.2f\n",cc);        }    }    return 0;}


[编程题]蘑菇阵
现在有两个好友A和B,住在一片长有蘑菇的由n*m个方格组成的草地,A在(1,1),B在(n,m)。现在A想要拜访B,由于她只想去B的家,所以每次她只会走(i,j+1)或(i+1,j)这样的路线,在草地上有k个蘑菇种在格子里(多个蘑菇可能在同一方格),问:A如果每一步随机选择的话(若她在边界上,则只有一种选择),那么她不碰到蘑菇走到B的家的概率是多少?

输入描述:
第一行N,M,K(2 ≤ N,M ≤ 20, k ≤ 100),N,M为草地大小,接下来K行,每行两个整数x,y,代表(x,y)处有一个蘑菇。


输出描述:
输出一行,代表所求概率(保留到2位小数)

输入例子:
2 2 12 1

输出例子:
0.50
思路:由于每个格子除边界只能向两个方向出度,那么对于每个格子除边界也有两个地方的入度;我们把问题分解,对于当前位置的方法数是他入度方法数的*0.5的和,这里特别注意边界,由于他只有一个方向出度,所以概率不是乘以0.5而是乘以1;(对了,有蘑菇的地方标记下,p=0)

想清楚了,就很简单了。

#include<stdio.h>#include<string.h>int main(){    double p[25][25],vis[25][25];    int n,m,k;    while(scanf("%d%d%d",&n,&m,&k)!=EOF)    {        memset(p,0,sizeof(p));        memset(vis,0,sizeof(vis));        int x,y;        for(int i=0;i<k;i++)        {            scanf("%d%d",&x,&y);            vis[x][y]=1;        }        p[1][1]=1;        if(vis[1][1]||vis[n][m]) {printf("0.00\n");continue;}        for(int i=1;i<=n;i++)        {            for(int j=1;j<=m;j++)            {                if(i==1&&j==1) continue;                if(vis[i][j]) p[i][j]=0;                else                {                    if(j==m) p[i][j]+=p[i-1][j]*0.5;                    if(i==n) p[i][j]+=p[i][j-1]*0.5;                    p[i][j]+=p[i-1][j]*0.5+p[i][j-1]*0.5;                }            }        }        printf("%.2f\n",p[n][m]);    }    return 0;}

这次的编程题都不是很难,我在练习的时候没有把握好时间,最后一题来不及写了。

0 0