1. 程式人生 > >美團點評2017秋招筆試編程題

美團點評2017秋招筆試編程題

%d stdin += can for 可能 array ont true

美團點評2017秋招筆試編程題

1, 大富翁遊戲,玩家根據骰子的點數決定走的步數,即骰子點數為1時可以走一步,點數為2時可以走兩步,點數為n時可以走n步。求玩家走到第n步(n<=骰子最大點數且是方法的唯一入參)時,總共有多少種投骰子的方法。

題解:

  寫出前面的幾個, 1 -> 1; 2 -> 2 ; 3 -> 4; 4 -> 8; 5 -> 16; 6 -> 32; 可以得到是 二的 n-1 次冪。

#include <cstdio>
 
int main(){
     
    int n, ans;
    while(scanf("%d", &n) != EOF){
        if(n <= 0){
            printf("%d\n", 0);
            continue;
        }
        ans = 1;
        for(int i=1; i<n; ++i){
            ans *= 2;
        }
        printf("%d\n", ans);
    }
    return 0;
}

  

2, 給你六種面額 1、5、10、20、50、100 元的紙幣,假設每種幣值的數量都足夠多,編寫程序求組成N元(N為0~10000的非負整數)的不同組合的個數。

題解:

  多一個 bill 選項, 則可以從 該bill 值的 0,1,2 ... j/bill , 這麽多種集合。dp[i][j] = dp[i][j] + dp[i-1][j - k*bill[i] ];

#include <iostream> 
#include <cstdio> 
#include <cstring> 
#include <cstdlib> 
using namespace std; 
const int MAXN = 10000 + 10; 
const int BILL[6] = {1, 5, 10, 20, 50, 100}; 

int n, dp[6][MAXN]; 

void init(){
    memset(dp, 0, sizeof(dp)); 
    for(int i=0; i<MAXN; ++i){
        dp[0][i] = 1; 
    }
    for(int i=1; i<6; ++i){
        for(int j=1; j<MAXN; ++j){
            for(int k=0; k*BILL[i] <= j; ++k){
                dp[i][j] += dp[i-1][j - k*BILL[i]]; 
            }
        }
    }
}

int main(){
    freopen("in.txt", "r", stdin); 

    init(); 
    while(scanf("%d", &n) != EOF){
        printf("%d\n", dp[5][n] );
    }
    return 0; 
}

  

3, 給定一組非負整數組成的數組h,代表一組柱狀圖的高度,其中每個柱子的寬度都為1。 在這組柱狀圖中找到能組成的最大矩形的面積(如圖所示)。 入參h為一個整型數組,代表每個柱子的高度,返回面積的值。

題解:

  經典的最大矩形問題。使用 left and right array, 分別記錄每一個pt可以擴展的最大距離。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int MAXN = 10000 + 10;
 
int n, tmp, ans, num[MAXN], lft[MAXN], rgt[MAXN];
 
 
int main(){
 
    while(scanf("%d", &n) != EOF){
        for(int i=1; i<=n; ++i){
            scanf("%d", &num[i]);
        }
        num[0] = num[n+1] = 0;
 
        for(int i=1; i<=n; ++i){
            tmp = i - 1;
            while(num[i] <= num[tmp]){
                tmp = lft[tmp] - 1;
            }
            lft[i] = tmp + 1;
        }
 
        for(int i=n; i>=1; --i){
            tmp = i + 1;
            while(num[i] <= num[tmp]){
                tmp = rgt[tmp] + 1;
            }
            rgt[i] = tmp - 1;
        }
        ans = 0;
        for(int i=1; i<=n; ++i){
            ans = max(ans, num[i]*(rgt[i] - lft[i] + 1));
        }
        printf("%d\n", ans );
    }
    return 0;
}

  

4, 給出兩個字符串(可能包含空格),找出其中最長的公共連續子串,輸出其長度。

題解:

  使用 動態規劃。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int MAXN = 100 + 10;
 
char ch1[MAXN], ch2[MAXN];
 
int dp[MAXN][MAXN];
 
int get_line(char *line, int max_size){
    int c, len = 0;
    while( (c = getchar()) != EOF && len < max_size ){
        line[len++] = c;
        if(c == ‘\n‘){
            break;
        }
    }
    line[len] = ‘\0‘;
    return (len - 1);
}
 
int main(){ 
 
    int ans = 0;
    int len1 = get_line(ch1, MAXN);
    int len2 = get_line(ch2, MAXN);
 
    memset(dp, 0, sizeof(dp));
    for(int i=0; i<len1; ++i){
        for(int j=0; j<len2; ++j){
            if(ch1[i] == ch2[j]){
                dp[i+1][j+1] = max(dp[i+1][j+1], dp[i][j]+1);
                ans = max(ans, dp[i+1][j+1]);
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}

  

美團點評2017秋招筆試編程題