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

題目1

  • 大富翁遊戲,玩家根據骰子的點數決定走的步數,即骰子點數爲1時能夠走一步,點數爲2時能夠走兩步,點數爲n時能夠走n步。求玩家走到第n步(n<=骰子最大點數且是方法的惟一入參)時,總共有多少種投骰子的方法。
  • 概括:f(n) = f(n-1)+f(n-2)+f(n-3)+....+f(1)+1,f(1)=1,f(2)=2.則f(n)=2^(n-1).

題目2

  • 給你六種面額 一、五、十、20、50、100 元的紙幣,假設每種幣值的數量都足夠多,編寫程序求組成N元(N爲0~10000的非負整數)的不一樣組合的個數。

題目3

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

題目4

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

AC代碼

#include<iostream>
#include<math.h>

#include <vector>
#include <string>
#include <deque>
#include <stack>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>

#include <algorithm>
#include <functional>
#include <numeric> //accmulate

using namespace std;


int GetLongestComSub(string str1,string str2)
{
    int m = str1.size();
    int n = str2.size();

    vector<vector<int >> vecs(m + 1, vector<int>(n + 1, 0));
    int max_len = 0;

    for (int i = 0; i < m;i++)
    {
        for (int j = 0; j < n;j++)
        {
            if (str1[i]==str2[j])
            {
                vecs[i + 1][j + 1] = vecs[i][j]+1;
                if (max_len<vecs[i+1][j+1])
                {
                    max_len = vecs[i+1][j+1];
                }
            }
        }
    }

    return max_len;
}
//
//測試用例:
//Sit it out G
//Sit down and shut up

//cin輸入字符串的總結:
//
//遇空字符(包括空格、回車、TAB)表示一個輸入的結束,連續的空字符會被忽略。
int main()
{
    string str1, str2;
    /*cin >> str1;
    cin >> str2;*/
    getline(cin, str1);
    getline(cin, str2);

    cout<<GetLongestComSub(str1,str2)<<endl;

    return 0;
}



int  GetMaxRect(vector<int>& vec)
{
    int max_area = vec[0];

    for (int i = 1; i < vec.size();i++)
    {
        int low = i - 1, high = i + 1;
        while (low >= 0 && vec[i] <= vec[low])
            low--;  
        while (high<vec.size() && vec[i] <= vec[high])
            high++;
            
        max_area = max(max_area, vec[i] * (high - low-1));
    }

    return max_area;
}

int main()
{
    int n;
    cin >> n;
    vector<int> vec;
    int temp = 0;
    for (int i = 0; i < n;i++)
    {
        cin >> temp;
        vec.push_back(temp);
    }

    cout << GetMaxRect(vec) << endl;

    return 0;
}


int main()
{
    int n;
    cin >> n;

    int table[] = { 1, 5, 10, 20, 50, 100 }; //6種面額
    //數字很大時,int表示不夠  
    vector<vector<long long>> dp(sizeof(table) / sizeof(int), vector<long long>(n + 1, 0)); //dp[i][j]表示用前(i+1)中面額組合成j面額的方法數
    for (int j = 0; j <= n; j++)
    {
        dp[0][j] = 1;
    }
    for (int i = 1; i < 6; i++)
    {
        for (int j = 0; j <= n; j++)
        {
            for (int k = 0; k <= j / table[i]; k++) //j=0時,dp[i][j] = dp[i - 1][j]
            {
                dp[i][j] += dp[i - 1][j - k*table[i]];
            }
        }
    }

    cout << dp[5][n] << endl;
    return 0;
}

/*動態規劃
須要拼湊的面額是n,
維護dp[i],表示取到i時的組合數目,dp[0]=1,
面額數組a[6]={1,5,10,20,50,100},
dp[j]=dp[j]+dp[j-a[i]],約數條件j>a[i]。
由於面額數目任意,因此須要分別處理只有面額1時,組合錢數爲1~n的各自組合數dp[1]~dp[n],
而後有面額1,5時,組合錢數爲1~n的各自組合數dp[1]~dp[n],依此內推。。。詳情見程序。
*/
#include<iostream>  
#include<vector>  
using namespace std;

int main()
{
    int n;
    cin >> n;
    int a[6] = { 1, 5, 10, 20, 50, 100 };
    vector<long> dp(n + 1, 0);   //當數字很大時,int表示不夠  
    dp[0] = 1;
    for (int i = 0; i < 6; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            if (j >= a[i])
                dp[j] = dp[j] + dp[j - a[i]];   //j值取和不取兩種狀況組合數目之和  
        }
    }
    cout << dp[n] << endl;
    return 0;
}

int main()
{
    int n;
    cin >> n;
    
    int* fn = new int[n];
    fn[0] = 1;
    fn[1] = 2;
    
    for (int i = 2; i < n;i++)
    {
        int ret = 0;
        for (int j = 0; j < i;j++)
        {
            ret += fn[j];
        }
        fn[i] = ret + 1;
    
    }
    cout << fn[n - 1] << endl;
    return 0;
}
相關文章
相關標籤/搜索