滴滴出行2017秋招笔试真题-编程题汇总_Java实现

滴滴出行2017秋招笔试真题-编程题汇总_Java实现
注:有的题参考别人的思路,用我最容易理解的代码编的程序,所以可以不能最优的解法,后续我会进行更新,只是一个思路,我的笔记而已,所以不喜勿喷~~~
我会将具体将具体参考代码的博客放在后面,若有侵权,请告知我,我会立刻删除。
滴滴出行2017秋招笔试真题-编程题汇总_Java实现_第1张图片
(1)连续最大和
解题思路:这个简单,就是定义一个sum,遍历数组,若是sum<0,说明前面的数组并不好,所以sum=temp[i], 否则,当前的值是可以补偿负数的,所以sum+=temp[i].
(2) 地下迷宫
回溯法
(3) 末尾0的个数
看n里面有多少个5
(4) 餐馆
解题思路:参考牛客网评论区
(5) 进制转换
(6) 数字和为sum的方法数
参考链接:https://blog.csdn.net/qq_43109561/article/details/90488445

习题及代码实现:

1. [编程题]连续最大和
时间限制:1秒
空间限制:32768K
一个数组有 N 个元素,求连续子数组的最大和。 例如:[-1,2,1],和最大的连续子数组为[2,1],其和为 3
输入描述:
输入为两行。 第一行一个整数n(1 <= n <= 100000),表示一共有n个元素 第二行为n个数,即每个元素,每个整数都在32位int范围内。以空格分隔。
输出描述:
所有连续子数组中和最大的值。
输入例子1:
3 -1 2 1
输出例子1:
3

代码实现:

import java.util.*;
public class Main{
    public static void main(String [] args){
        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        int [] temp=new int[n];
        for(int i=0;i0){
                sum+=temp[i];
            }else{
                sum=temp[i];
            }
            max=Math.max(max,sum);
        }
        return max;
    }
}


2. [编程题]地下迷宫
时间限制:1秒
空间限制:32768K
小青蛙有一天不小心落入了一个地下迷宫,小青蛙希望用自己仅剩的体力值P跳出这个地下迷宫。为了让问题简单,假设这是一个n*m的格子迷宫,迷宫每个位置为0或者1,0代表这个位置有障碍物,小青蛙达到不了这个位置;1代表小青蛙可以达到的位置。小青蛙初始在(0,0)位置,地下迷宫的出口在(0,m-1)(保证这两个位置都是1,并且保证一定有起点到终点可达的路径),小青蛙在迷宫中水平移动一个单位距离需要消耗1点体力值,向上爬一个单位距离需要消耗3个单位的体力值,向下移动不消耗体力值,当小青蛙的体力值等于0的时候还没有到达出口,小青蛙将无法逃离迷宫。现在需要你帮助小青蛙计算出能否用仅剩的体力值跳出迷宫(即达到(0,m-1)位置)。

输入描述:
输入包括n+1行:
第一行为三个整数n,m(3 <= m,n <= 10),P(1 <= P <= 100)
接下来的n行:
每行m个0或者1,以空格分隔

输出描述:
如果能逃离迷宫,则输出一行体力消耗最小的路径,输出格式见样例所示;如果不能逃离迷宫,则输出"Can not escape!"。 测试数据保证答案唯一

输入例子1:
4 4 10 1 0 0 1 1 1 0 1 0 1 1 1 0 0 1 1

输出例子1:
[0,0],[1,0],[1,1],[2,1],[2,2],[2,3],[1,3],[0,3]

代码实现:

import java.util.*;
public class Main{
    public static void main(String [] args){
            Scanner in=new Scanner(System.in);
            int n=Integer.parseInt(in.next());
            int m=Integer.parseInt(in.next());
            int p=Integer.parseInt(in.next());
            int [][] temp=new int[n][m];
            for(int i=0;i= 0)
                    res = str + "[0," + (m - 1) + "]";
                else
                    res = "Can not escape!";
      
                return;
            }
            // 从这一点往四个方向走:还没有走到头
            if(row=0 && col>=0 && temp[row][col]==1&& !flag[row][col]) {
                flag[row][col]=true;//往这一点走
                str+="["+row+","+col+"],";
                //水平向右走
                getRes(temp,flag,row,n,col+1,m,str,p-1);
                //向下走:不消耗能量
                getRes(temp,flag,row+1,n,col,m,str,p);
                //水平向左走
                getRes(temp,flag,row,n,col-1,m,str,p-1);
                //向上走
                getRes(temp,flag,row-1,n,col,m,str,p-3);
            }
        }
}


3. [编程题]末尾0的个数
时间限制:1秒
空间限制:32768K
输入一个正整数n,求n!(即阶乘)末尾有多少个0? 比如: n = 10; n! = 3628800,所以答案为2

输入描述:
输入为一行,n(1 ≤ n ≤ 1000)

输出描述:
输出一个整数,即题目所求

输入例子1:
10

输出例子1:
2

代码实现:

/*
计算这些数中有多少个5
*/
import java.util.*;
public class Main{
    public static void main(String [] args){
        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        int res=getRes(n);
        System.out.println(res);
    }
    public static int getRes(int n){
        int res=0;
        while(n>=5){
            n/=5;
            res+=n;
        }
        return res;
    }
}


4. [编程题]餐馆
时间限制:1秒
空间限制:65536K
某餐馆有n张桌子,每张桌子有一个参数:a 可容纳的最大人数; 有m批客人,每批客人有两个参数:b人数,c预计消费金额。 在不允许拼桌的情况下,请实现一个算法选择其中一部分客人,使得总预计消费金额最大

输入描述:
输入包括m+2行。 第一行两个整数n(1 <= n <= 50000),m(1 <= m <= 50000) 第二行为n个参数a,即每个桌子可容纳的最大人数,以空格分隔,范围均在32位int范围内。 接下来m行,每行两个参数b,c。分别表示第i批客人的人数和预计消费金额,以空格分隔,范围均在32位int范围内。

输出描述:
输出一个整数,表示最大的总预计消费金额

输入例子1:
3 5 2 4 2 1 3 3 5 3 7 5 9 1 10

输出例子1:
20


import java.util.*;
/*
 基本思路就是:桌子序列升序排列  ,客人按照预定花钱多少降序排序,然后贪心法从钱多的客人开始招呼。
 但是这题时间复杂度卡得太紧,在遍历能容得下第i批客人的时候需要二分查找去找否则超时
 */
public class Main {
	    public static void main(String [] args){
	        Scanner in=new Scanner(System.in);
	        int n=Integer.parseInt(in.next());
	        int m=Integer.parseInt(in.next());
	        int [] table=new int[n];
	        for(int i=0;i() {
				@Override
				public int compare(int[] o1, int[] o2) {
					return o2[1]-o1[1];
				}
			});
			//从桌子开始装人
	    	long sum=0;
	    	int index=0;//找桌子的位置
	    	boolean [] flag=new boolean[n];//n个桌子,从第i个客人找桌子
	    	for(int i=0;itable[n-1]) {
	    			continue;//客人比桌子最大安排数大,招待不了了
	    		}
	    		index=findTable(temp[i][0],table);
	    		while(index>1;
			    if(table[mid]>=target) {
			    	end=mid-1;
			    }else {
			    	start=mid+1;
			    }
			}
			return start;
		}
}

5. [编程题]进制转换
时间限制:1秒
空间限制:32768K
给定一个十进制数M,以及需要转换的进制数N。将十进制数M转化为N进制数

输入描述:
输入为一行,M(32位整数)、N(2 ≤ N ≤ 16),以空格隔开。

输出描述:
为每个测试实例输出转换后的数,每个输出占一行。如果N大于9,则对应的数字规则参考16进制(比如,10用A表示,等等)

输入例子1:
7 2

输出例子1:
111

代码实现:

import java.util.*;
public class Main{
    public static void main(String [] args){
        Scanner in=new Scanner(System.in);
        while(in.hasNext()){
            String [] s=in.nextLine().split(" ");
            int m=Integer.parseInt(s[0]);
            int n=Integer.parseInt(s[1]);
            int sign=0;
            if(m<0){
                sign=-1;
                m=-m;
            }
            String res=getRes(m,n);
            if(sign==-1){
                System.out.println("-"+res);
            }else{
                System.out.println(res);
            }
        }
        in.close();
    }
    public static String getRes(int m,int n){
        StringBuffer sb=new StringBuffer();
        //如果是二进制的
        while(m!=0){
            int ys=m%n;
            if(ys>9){
                //余数大于9的时候
                char c=(char)((ys-10)+'A');
                sb.append(c);
            }else{
                 sb.append(ys);
            }
            m/=n;
        }
        return sb.reverse().toString();
    }
}

6. [编程题]数字和为sum的方法数
时间限制:1秒
空间限制:32768K
给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数。
当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案。

输入描述:
输入为两行:
第一行为两个正整数n(1 ≤ n ≤ 1000),sum(1 ≤ sum ≤ 1000)
第二行为n个正整数Ai,以空格隔开。

输出描述:
输出所求的方案数

输入例子1:
5 15 5 5 10 2 3

输出例子1:
4

import java.util.*;
public class Main{
    public static void main(String [] args){
            Scanner in=new Scanner(System.in);
            int n=Integer.parseInt(in.next());
            int sum=Integer.parseInt(in.next());
            int[] temp = new int[n+1];
            for(int i=1; i<=n; i++){
                temp[i] =Integer.parseInt(in.next()); //in.nextInt();
            }
            //System.out.println(Arrays.toString(temp));
            long res=getRes(n,sum,temp);
            System.out.println(res);
        }
        public static long getRes(int n,int sum,int [] temp){
            //前i个人组成j的个数
            //dp[i,j]表示前i个可以凑到j的个数
            long [] [] dp=new long[n+1][sum+1];
            //初始化
            //前i个人组成j的个数为0;
            for(int i=0;i<=n;i++) {
                dp[i][0]=1;
            }
            for(int i=1; i<=n; i++){
                for(int j=0; j<=sum; j++){
                    //等于拿了这个数据和没拿这个数据的方案总和,没拿时只需要看前i-1个数据组成j-p[i]的方案数
                    if(temp[i] <= j){
                        dp[i][j] = dp[i-1][j] +dp[i-1][j-temp[i]]; 
                    }else{//p[i]>j时只能选择不拿
                        dp[i][j] = dp[i-1][j];
                    }
                }
            }
            return dp[n][sum];
        }
}

你可能感兴趣的:(公司真题)