1. 程式人生 > >百度2016研發工程師線上程式設計題

百度2016研發工程師線上程式設計題

[程式設計題]罪犯轉移 C市現在要轉移一批罪犯到D市,C市有n名罪犯,按照入獄時間有順序,另外每個罪犯有一個罪行值,值越大罪越重。現在為了方便管理,市長決定轉移入獄時間連續的c名犯人,同時要求轉移犯人的罪行值之和不超過t,問有多少種選擇的方式? 

輸入描述:
第一行資料三個整數:n,t,c(1≤n≤2e5,0≤t≤1e9,1≤c≤n),第二行按入獄時間給出每個犯人的罪行值ai(0≤ai≤1e9)


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

輸入例子:
3 100 2
1 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)表示網格上的點


輸出描述:
一行輸出最小面積

輸入例子:
2
0 0
0 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 1
0.2 0.1
0.1 0.4

輸出例子:
equal
0.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 1
2 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;
}

這次的程式設計題都不是很難,我在練習的時候沒有把握好時間,最後一題來不及寫了。