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

题目来源,题目还算是比较简单,都是acm的基础题目,但是好久没有做题了啊,感觉有点吃力,脑子有点转不动了,以此告诫自己
做完之后回头来看,其实每一道题都可以找规律找到做法,很巧妙的做出来,可以不使用非常高深的做法,复杂度也不用优化到极致

第一题:大富翁游戏

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

题解:
数据量小到极致,6都告诉你了,你花两分钟把前面算出来就完了对不?完了还发现有规律

#include<bits/stdc++.h>
int a[]={1,2,4,8,16,32};
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
        printf("%d\n",a[n-1]);
    return 0;
}

第二题:拼凑钱币

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

题解:

牛客网本题的一个解释很详细了,先看下图再看下一行的个人理解
这里一个可能难想到的一个点就是dp[j-money[i]],这个怎么理解呢:假设任意面值的纸币做为最小面值的时候,都是从1开始累加的
例如:一块钱是最小的时候(本身确实是最小的),很容易看得出是所有数值金额都只有一种拼凑方法
五块钱的时候:5,10,15,20…..也都是一样的,以此类推。
动态规划的思想之一就是把所有东西都等同看待,然后状态转移方程就很容易写出来了

这里写图片描述

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define maxn 10005
LL dp[maxn];
int money[]={1,5,10,20,50,100};
int main()
{
    int n;
    while(scanf("%d",&n) != EOF) {
        memset(dp, 0, sizeof(dp));
        dp[0] = 1;
        for(int i = 0;i < 6; i++) {
            for(int j = money[i]; j <= n; j++)
                dp[j] += dp[j - money[i]];
        }
        printf("%lld\n",dp[n]);
    }
    return 0;
}

第三题:最大矩形面积

给定一组非负整数组成的数组h,代表一组柱状图的高度,其中每个柱子的宽度都为1。 在这组柱状图中找到能组成的最大矩形的面积(如图所示)。 入参h为一个整型数组,代表每个柱子的高度,返回面积的值

这里写图片描述

题解:
一种直接暴力,n*n的复杂度
一种利用单调栈的做法

#include <bits/stdc++.h>
using namespace std;
#define maxn 10005
typedef long long LL;
LL a[maxn];
int main()
{
    int n;
    while(scanf("%d",&n) != EOF) {
        for(int i = 1; i <= n; i++)
            scanf("%lld",&a[i]);
        LL ans=a[1];
        for(int i = 1; i <= n; i++) {
            LL min_h=a[i];
            for(int j = i+1; j <= n; j++) {
                min_h = min(min_h, a[j]);
                ans = max(ans, (j-i+1)*min_h);
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}

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

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

题解:
这里一个没有注意的地方就是字符串里面还包含了空格

最长公共连续子串 和 最长公共子串不一样,一个连续一个不连续,不连续的也就多了一点点不一样的东西,大家可以网上找找看
本题状态转移方程因为是连续的所以就很简单啦:dp[i+1][j+1]=dp[i][j]+1;

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int dp[100][100];
    char a[100],b[100];
    while(gets(a)){
        gets(b);
        int a1=strlen(a);
        int b1=strlen(b);
        memset(dp,0,sizeof(dp));
        int ans=0;
        for(int i=0;i<a1;i++){
            for(int j=0;j<b1;j++){
                if(a[i]==b[j])
                    dp[i+1][j+1]=dp[i][j]+1;
                ans=max(ans,dp[i+1][j+1]);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值