美团点评2017秋招笔试编程

原文:https://blog.csdn.net/LCBSSG/article/details/76473239

一、
大富翁游戏,玩家根据骰子的点数决定走的步数,即骰子点数为1时可以走一步,点数为2时可以走两步,点数为n时可以走n步。求玩家走到第n步(n<=骰子最大点数且是方法的唯一入参)时,总共有多少种投骰子的方法。
输入描述:
输入包括一个整数n,(1 ≤ n ≤ 6)
输出描述:
输出一个整数,表示投骰子的方法
示例1
输入
6
输出
32

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()) {
            int n = sc.nextInt();
            /* 一开始想用动态规划,结果发现更简单的办法,所以不用总是一来就动态规划
             * f(n)=f(n-1)+...+f(1)+1 ①
             * f(n-1)=f(n-2)+...+f(1)+1 ②
             * ②-①得到f(n)=f(n-1)*2
             */
            System.out.println((int)Math.pow(2, n - 1));
        }
        sc.close();
    }
}


给你六种面额 1、5、10、20、50、100 元的纸币,假设每种币值的数量都足够多,编写程序求组成N元(N为0~10000的非负整数)的不同组合的个数。
输入描述:
输入包括一个整数n(1 ≤ n ≤ 10000)
输出描述:
输出一个整数,表示不同的组合方案数
示例1
输入
1
输出
1

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        /*背包问题
        只用第一种面额时,装入背包都只有一种方式
        当使用前两种面额时,装满背包除了原来的方式外,还可以用新的面额组合
        */
        while(sc.hasNext()) {
            int n = sc.nextInt();
            int money[]={1, 5, 10, 20, 50, 100};//dp看做背包的容量
            long[]dp = new long[n+1];
            //--------------------初始化-----------------------
            dp[0] = 1;
            //----------------------规划-----------------------
            for(int i = 0; i < 6; i++){//money[i]看做物品重量
                for(int j=money[i];j<=n;j++){
                    dp[j] += dp[j-money[i]];
                }
            }
            System.out.println(dp[n]);
        }
        sc.close();
    }
}

三、
给定一组非负整数组成的数组h,代表一组柱状图的高度,其中每个柱子的宽度都为1。 在这组柱状图中找到能组成的最大矩形的面积。 入参h为一个整型数组,代表每个柱子的高度,返回面积的值。
输入描述:
输入包括两行,第一行包含一个整数n(1 ≤ n ≤ 10000)
第二行包括n个整数,表示h数组中的每个值,h_i(1 ≤ h_i ≤ 1,000,000)
输出描述:
输出一个整数,表示最大的矩阵面积。
示例1
输入
6
2 1 5 6 2 3
输出
10

方法一:

思路

其实只要掌握一点,这道题目就比较好解了。那就是分析清楚,最大的矩形面积是由什么构成的。其实最直接的一个想法,就是找出所有能够构成的矩形,然后找到其中最大的一个。那要怎么样能够遍历所有的矩形呢?其实每个构成的矩形的高,都是某一个柱状图的高,也就是那个矩形,最低的柱状图的高。所以以每一个柱状图为中心,向两边展开,找到大于等于自己的柱状图,就归位面积的一部分,一直扫面到小于自身高度的停止。然后和现有最大面积比较。最后得到最大面积。
这个思路可以解决问题,但是,其效率可想而知,如果这是一个递增的数组,基本上每个柱状图就都要遍历一遍数组,效率就显得十分的低下了。

import java.util.*;
public class demo{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] arr = new int[n];
        for(int i = 0; i < n; i++)
            arr[i] = sc.nextInt();
        System.out.println(solution(arr, n));
        return;
    }

    public static int solution(int[] arr, int len){
        int max = 0;
        for(int i = 0; i < len; i++){
            int count = 1;
            int j = i;
            if(i == 0){
                while(++j < len && arr[j] >= arr[i]) count++;
            } else if(i == len-1) {
                while(--j > 0 && arr[j] >= arr[i]) count++;
            } else{
                while(++j < len && arr[j] >= arr[i]) count++;
                j = i;
                while(--j > 0 && arr[j] >= arr[i]) count++;
            }
            if(arr[i]*count >= max) max = arr[i]*count;
        }
        return max;
    }
}

方法二:

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()) {
            int n = sc.nextInt();
            int a[] = new int[n];
            for(int i = 0; i < n; i++) {
                a[i] = sc.nextInt();
            }
            Stack<Integer> stk = new Stack<>();
            stk.add(0);
            int i = 1, max = a[0];
            while(i <= n) {//i作为矩形右边界
                if(i == n && !stk.isEmpty()) {
                    int j = stk.pop();
                    max = Math.max(max, a[j] * (stk.isEmpty()?i:i-stk.peek()-1));
                }else {
                    if(stk.isEmpty()||a[i]>=a[stk.peek()]){//找局部峰值
                        stk.add(i++);
                    }else{
                        int j=stk.pop();
                        max=Math.max(max, a[j]*(stk.isEmpty()?i:i-stk.peek()-1));
                    }
                }
            }
            System.out.println(max);
        }
        sc.close();
    }
}

方法三:

思路:i到j之间最小高度乘以 i-j+1, 一次查询

def GetNum(n, array):
    maxArea = 0
    for i in range(n):
        minhigh = array[i]
        for j in range(i, n):
            minhigh = min(minhigh, array[j])
            maxArea = max(maxArea, minhigh*(j-i+1))

    return maxArea


if __name__ == '__main__':
    n = input()
    array = [int(i) for i in raw_input().split()]

    res = GetNum(n, array)
    print res

四、
给出两个字符串(可能包含空格),找出其中最长的公共连续子串,输出其长度。
输入描述:
输入为两行字符串(可能包含空格),长度均小于等于50.
输出描述:
输出为一个整数,表示最长公共连续子串的长度。
输入
abcde
abgde
输出
2

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        String s1=sc.nextLine();
        String s2=sc.nextLine();
        sc.close();
        int len1=s1.length();
        int len2=s2.length();
        int [][]dp=new int[len1][len2];
        for(int i=0;i<len1;i++){
            if(s1.charAt(i)==s2.charAt(0)){
                dp[i][0]=1;
            }
        }
        for(int i=0;i<len2;i++){
            if(s2.charAt(i)==s1.charAt(0)){
                dp[0][i]=1;
            }
        }
        int max=dp[0][0];
        for(int i=1;i<len1;i++){
            for(int j=1;j<len2;j++){
                if(s1.charAt(i)==s2.charAt(j)){
                    dp[i][j]=dp[i-1][j-1]+1;//dp[i][j]表示到s1的第i个字符和s2的第j个字符时,连续子串的长度
                }
                if(dp[i][j]>max){
                    max=dp[i][j];
                }
            }
        }

        System.out.println(max);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值