美团点评2017秋招笔试编程题 - 题解

昨晚临时做了下美团2017年的校招题(纯属无聊),感觉美团的题就做得很舒服了,考想法,代码量小,只要你的idea够好,代码就几行,学习了!

题目链接:[点这里].

第一题:大富翁游戏

题目:

大富翁游戏,玩家根据骰子的点数决定走的步数,即骰子点数为1时可以走一步,点数为2时可以走两步,点数为n时可以走n步。求玩家走到第n步(n<=骰子最大点数且是方法的唯一入参)时,总共有多少种投骰子的方法。

解析:

n很小,所以你直接算到6就好了,我一开始就没多想,直接记忆化搜了下.这个题和走楼梯那个题想法是一样的.

代码:

#include 

using namespace std;

int dp[7];

int dfs(int n)
{
    if (n == 1)
        return dp[1] = 1;
    if (dp[n])
        return dp[n];
    int ret = 1;
    for (int i = 1; i < n; i++)
        ret += dfs(i);
    return dp[n] = ret;
}

int main()
{
    dfs(6);
    int n;
    while (cin >> n)
        cout << dp[n] << endl;
    return 0;
}

其实这个题有更简单的方法,就是推通项公式.

dp[n]=dp[n1]+dp[n2]++dp[1]
dp[n1]=dp[n2]++dp[1]
两个等式相减,得到: dp[n]=dp[n1]2,dp[1]=1 ,即 dp[n]=2n1 ,所以下面的代码更好.

#include 

using namespace std;

int main()
{
    int n;
    while (cin >> n)
        cout << pow(2, n - 1) << endl;
    return 0;
}

第二题:拼凑钱币

题目:

给你六种面额 1、5、10、20、50、100 元的纸币,假设每种币值的数量都足够多,编写程序求组成N元(N为0~10000的非负整数)的不同组合的个数。

解析:

首先我想到的是动态规划,类似于整数拆分, dp[i][j] 表示,面值为i的钱拿出 value[j] 块钱有多少种方案,那么为了避免重复, dp[i][j] 可以由 jk=0dp[ivalue[j]][k] 转移过来,初始化的时候 dp[value[i]][i]=1 ,最后面值为 n 的方案数为 6i=0dp[n][i]

代码:

#include 

using namespace std;

#define MAX_N 10001
#define MAX_Z 6

typedef long long LL;

int value[] = {1, 5, 10, 20, 50, 100};

int main()
{
    vector<vector > dp(MAX_N, vector(MAX_Z, 0));
    for (int i = 0; i < MAX_Z; i++)
        dp[value[i]][i] = 1;
    vector sum(MAX_N, 0);
    for (int i = 1; i < MAX_N; i++) {
        for (int j = MAX_Z - 1; j >= 0; j--) {
                if (i - value[j] <= 0)
                    continue;
                for (int k = j; k >= 0; k--) {
                    dp[i][j] += dp[i - value[j]][k];
                }
        }
    }
    for (int i = 1; i < MAX_N; i++)
        for (int j = 0; j < MAX_Z; j++)
            sum[i] += dp[i][j];
    int n;
    while (cin >> n)
        cout << sum[n] << endl;
    return 0;
}

仔细想想,这其实是一个完全背包问题嘛,先用面值为1的钱去填充,然后再用面值为5的钱去填充,这个时候得到的方案就是面值1和面值5的钱一起去填充的方案数,依次类推就可以了,可以看到完全背包问题可以转化为01背包问题,而且可以优化降维,确实很不错的解法。

#include 

using namespace std;

#define MAX_N 10001
#define MAX_Z 6

typedef long long LL;

int value[] = {1, 5, 10, 20, 50, 100};

int main()
{
    vector dp(MAX_N, 0);
    dp[0] = 1;
    for (int i = 0; i < MAX_Z; i++)
        for (int j = value[i]; j < MAX_N; j++)
            dp[j] += dp[j - value[i]];
    int n;
    while (cin >> n)
        cout << dp[n] << endl;
    return 0;
}

第三题:最大矩形面积

题目:

给定一组非负整数组成的数组h,代表一组柱状图的高度,其中每个柱子的宽度都为1。 在这组柱状图中找到能组成的最大矩形的面积(如图所示)。 入参h为一个整型数组,代表每个柱子的高度,返回面积的值。
美团点评2017秋招笔试编程题 - 题解_第1张图片

解析:

单调栈的裸题,这里就不多讲述了,百度搜单调栈基本都会出现这个题。

代码:

#include 

using namespace std;

typedef long long LL;

struct Node{
    LL id;
    LL value;
    Node() {}
    Node(LL id, LL value) : id(id), value(value) {}
};

int main()
{
    int n;
    while (~scanf("%d", &n)) {
        stack st;
        LL ans = 0;
        for (int i = 0; i < n; i++) {
            LL x;
            scanf("%lld", &x);
            LL pre = i;
            while (!st.empty() && st.top().value > x)
                ans = max(ans, (i - (pre = st.top().id)) * st.top().value), st.pop();
            st.emplace(pre, x);
        }
        while (!st.empty()) {
            ans = max(ans, (n - st.top().id) * st.top().value);
            st.pop();
        }
        printf("%lld\n", ans);
    }
    return 0;
}

第四题:最长公共连续子串

题目:

给出两个字符串(可能包含空格),找出其中最长的公共连续子串,输出其长度。

解析:

还是动态规划,类似最长公共子串,不过当str[i] != str[j]时,dp[i][j]=0,这是因为再往后即使有相同的字母也不是连续的了,要注意是连续的,忘记说了, dp[i][j] 表示字符串str1.substr(0,i),str2.(0,j)最长连续公共子串的长度,连续子串的结尾分别是i,j

代码:

#include 

using namespace std;

typedef long long LL;

int main()
{
    string str1, str2;
    while (getline(cin, str1)) {
        getline(cin, str2);
        vector<vector<int> > dp(str1.size() + 1, vector<int>(str2.size() + 1, 0));
        int ans = 0;
        for (int i = 1; i <= str1.size(); i++)
            for (int j = 1; j <= str2.size(); j++)
                dp[i][j] = str1[i - 1] == str2[j - 1] ? dp[i - 1][j - 1] + 1 : 0,
                ans = max(ans, dp[i][j]);
        cout << ans << endl;
    }
    return 0;
}

你可能感兴趣的:(笔试面试题,笔试面试题)