【滴滴】2017滴滴打人

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


输出描述:
所有连续子数组中和最大的值。
示例1

输入

3 -1 2 1

输出

3

以前的和大于等于0,继续向下相加;以前的和小于0,从下一位重新开始相加,否则越加越小

import java.util.Scanner;
 
public class Main {
 
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        //连续子数组最大的和
        int num=s.nextInt();
        int []arr=new int[num];
        for(int i=0;i<num;i++){
            arr[i]=s.nextInt();
        }
        maxSum(arr);
 
    }
    public static void maxSum(int []arr){
        int max=arr[0];
        int sum=arr[0];
        for(int i=1;i<arr.length;i++){
            //以前的和大于0继续加,以前的和小于0重新赋值
            if(sum>=0){
                sum+=arr[i];
            }else{
                sum=arr[i];
            }
            if(sum>=max){
                max=sum;
            }
        }
        System.out.println(max);
    }
 
 
}





某餐馆有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

输出

20

对顾客按钱数排序,钱数相同的按人数排序,运行超时

import java.util.Scanner;
 
class Customer {
    int PeoNum;
    int Price;
}
 
public class Main {
 
    public static void main(String[] args) {
        //贪心算法(?)
        /*
         * 3 5 2 4 2 1 3 3 5 1 3 5 7 9 10
         */
        //4 6 12 1 4 7 11 3 3 10 35 10 5 9 12 10 6 7
        Scanner s = new Scanner(System.in);
        // 桌子个数N,来的客人M
        int N = s.nextInt();
        int M = s.nextInt();
        // 每张桌子的容量
        int[] table = new int[N];
        for (int i = 0; i < N; i++) {
            table[i] = s.nextInt();
        }
        //桌子大小从小到大排序
        // 人数和消费金额
        Customer[] customers = new Customer[M];
        for (int i = 0; i < M; i++) {
            customers[i] = new Customer();
            customers[i].PeoNum = s.nextInt();
            customers[i].Price = s.nextInt();
        }
        //顾客按照消费金额多少排序大到小,如果消费金额相等按照人数排序
        Customer temp=new Customer();
        for (int i = 0; i < M; i++) {
            for(int j=i;j<M;j++){
                if(customers[i].Price<customers[j].Price){
                    temp=customers[i];
                    customers[i]=customers[j];
                    customers[j]=temp;
                }
                if(customers[i].Price==customers[j].Price){
                    if(customers[i].PeoNum<customers[j].PeoNum){
                        temp=customers[i];
                        customers[i]=customers[j];
                        customers[j]=temp;
                    }
                }
            }
        }
         
        Restaurant(table, customers);
 
    }
 
    public static void Restaurant(int[] table, Customer[] customers) {
        // 记录每桌最大消费和剩余人数
        int[] maxPrice = new int[table.length];
        for (int i = 0; i < table.length; i++) {
            for (int j = 0; j < customers.length; j++) {
                if (table[i] >= customers[j].PeoNum) {
                    if(customers[j].Price>maxPrice[i]){
                        maxPrice[i]=customers[j].Price;
                        customers[j].PeoNum=Integer.MAX_VALUE;
                    }
                }
                 
            }
             
        }
        int sum = 0;
        for (int i = 0; i < maxPrice.length; i++) {
            //System.out.print(maxPrice[i]+" ");
            sum += maxPrice[i];
        }
        System.out.println(sum);
    }
 
}





小青蛙有一天不小心落入了一个地下迷宫,小青蛙希望用自己仅剩的体力值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

输出

[0,0],[1,0],[1,1],[2,1],[2,2],[2,3],[1,3],[0,3]

递归,把可能的都走一遍然后选择需要能量最小的,记住最后需要把map[x][y]重新置为1,linkedlist也要把最后的remove掉

import java.util.Iterator;
import java.util.LinkedList;
import java.util.Scanner;
 
public class Main {
    private static int m = 0, n = 0, minCost = Integer.MAX_VALUE, p = 0;
    private static LinkedList<Point> linkedList = new LinkedList<>();
    private static String path = "";
 
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        m = in.nextInt();
        p = in.nextInt();
        int[][] map = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                map[i][j] = in.nextInt();
            }
        }
         
        generate(map, 0, 0, 0);
        if (minCost == Integer.MAX_VALUE) {
            System.out.println("Can not escape!");
        } else {
            System.out.println(path.substring(0, path.length() - 1));
        }
    }
 
    private static void generate(int[][] map, int x, int y, int currentCost) {
        if (currentCost > p)
            return;
        map[x][y] = 2;
        linkedList.offer(new Point(x, y));
        if (x == 0 && y == m - 1) {
            if (currentCost < minCost) {
                minCost = currentCost;
                savePath();
            }
            map[x][y] = 1;
            linkedList.removeLast();
            return;
        }
        if (x < n - 1 && map[x + 1][y] == 1) {// down
            generate(map, x + 1, y, currentCost);
        }
        if (x > 0 && map[x - 1][y] == 1) {// up
            generate(map, x - 1, y, currentCost + 3);
        }
        if (y < m - 1 && map[x][y + 1] == 1) {// right
            generate(map, x, y + 1, currentCost + 1);
        }
        if (y > 0 && map[x][y - 1] == 1) {// left
            generate(map, x, y - 1, currentCost + 1);
        }
        map[x][y] = 1;
        linkedList.removeLast();
    }
 
    private static void savePath() {
        Iterator<Point> iterator = linkedList.iterator();
        StringBuilder sb = new StringBuilder();
        while (iterator.hasNext()) {
            Point point = iterator.next();
            sb.append("[").append(point.x).append(",").append(point.y).append("],");
        }
        path = sb.toString();
    }
 
    private static class Point {
        int x = 0;
        int y = 0;
 
        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
}




输入一个正整数n,求n!(即阶乘)末尾有多少个0? 比如: n = 10; n! = 3628800,所以答案为2
输入描述:
输入为一行,n(1 ≤ n ≤ 1000)


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

输入

10

输出

2

分析:https://blog.csdn.net/shubingzhuoxue/article/details/52575999

对N进行质因数分解 N=2^x * 3^y * 5^z...,由于10 = 2*5,所以末尾0的个数只和x与z有关,每一对2和5相乘可以得到一个10,于是末尾0的个数=min(x,z)。在实际中x是远远大于z的,所以我们只要求出z的值即可。
  根据公式
  z = N/5 + N/5^2 + N/5^3+...+N/5^k
  这表明,5的倍数贡献了一个5,5^2的倍数又贡献了一个5...。

  比如:25其实是贡献了2个5,但是在N/5中已经贡献了一个,所以在N/5^2中再贡献一个;同样,125在N/5中贡献一个,在N/5^2中贡献一个,在N/5^3中再贡献一个,一共是3个。

import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int num=sc.nextInt();
        //countZero=N/5+N/5/5+N/5/5/5+...[直到N为0截止]
        int countZero=0;
        while(num>0){
            countZero+=num/5;
            num=num/5;
        }
        System.out.println(countZero);
    }
 
}






给定一个十进制数M,以及需要转换的进制数N。将十进制数M转化为N进制数
输入描述:
输入为一行,M(32位整数)、N(2 ≤ N ≤ 16),以空格隔开。


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

输入

7 2

输出

111

进制转换,不难,但是需要考虑负数

import java.util.*;
 
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int m = sc.nextInt();
        int N = sc.nextInt();
        int M = 0;
        // 如果M是负数,把他变成正数求
        if (m < 0) {
            M = -m;
        } else {
            M = m;
        }
 
        List list = new ArrayList();
        while (M / N != 0) {
            list.add(Switch(M % N));
            M = M / N;
        }
        list.add(Switch(M % N));
        if (m < 0) {
            list.add('-');//负数前面加负号
        }
        for (int i = list.size() - 1; i >= 0; i--) {
            System.out.print(list.get(i));
        }
 
    }
 
    public static char Switch(int m) {
        char result = ' ';
        // 大写字母A的asc码65
        int plus = 65;
        // 小于9直接返回
        if (m <= 9) {
            return (char) (m + 48);
        }
        plus += m - 10;
        result = (char) plus;
        return result;
    }
 
}





给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数。

当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案。 
输入描述:
输入为两行:
 第一行为两个正整数n(1 ≤ n ≤ 1000),sum(1 ≤ sum ≤ 1000)
 第二行为n个正整数A[i](32位整数),以空格隔开。


输出描述:
输出所求的方案数
示例1

输入

5 15 5 5 10 2 3

输出

4

这道题要跟2017美团的钱的那道题区分开,看起来很相似;但是那个组成部分可以重复,这个不可以;那个内层循环是从前向后,这个是从后向前,否则会算多了,这个属于背包0-1问题


import java.util.*;
 
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int sum = in.nextInt();
        int[] value = new int[n];
        long[] dp = new long[sum + 1];
        dp[0] = 1;
        for (int i = 0; i < n; i++) {
            value[i] = in.nextInt();
        }
        for (int i = 0; i < n; i++) {
            for (int j = sum; j >=value[i]; j--) {
                dp[j] += dp[j - value[i]];
            }
//          for(int k=0;k<dp.length;k++){
//              System.out.print(dp[k]+" ");
//          }
//          System.out.println();
        }
        System.out.println(dp[sum]);
 
    }
 
}

猜你喜欢

转载自blog.csdn.net/wenyimutouren/article/details/80586117
今日推荐