刷题记录之校招编程题目篇

 

获得最多的奖金

题目描述

小明在越南旅游,参加了当地的娱乐活动。小明运气很好,拿到了大奖, 到了最后的拿奖金环节。小明发现桌子上放着一列红包,每个红包上写着奖金数额。

现在主持人给要求小明在这一列红包之间“切”2刀,将这一列红包“切”成3组,并且第一组的奖金之和等于最后一组奖金和(允许任意一组的红包集合是空)。最终第一组红包的奖金之和就是小明能拿到的总奖金。小明想知道最多能拿到的奖金是多少,你能帮他算算吗。

 

举例解释:桌子上放了红包  1, 2, 3, 4, 7, 10。小明在“4,7”之间、“7,10” 之间各切一刀,将红包分成3组 [1, 2, 3, 4]   [7]   [10],其中第一组奖金之和=第三组奖金之和=10,所以小明可以拿到10越南盾。

输入描述:
第一行包含一个正整数n,(1<=n<= 200 000),表示有多少个红包。
第二行包含n个正整数d[i],表示每个红包包含的奖金数额。其中1<= d[i] <= 1000 000 000

输出描述:
小明可以拿到的总奖金

示例1
输入
5
1 3 1 1 4
输出
5
说明
[1,3,1]  [ ]   [1,4] ,其中第一组奖金和是5,等于第三组奖金和。所以小明可以拿到5越南盾

示例2
输入
5
1 3 2 1 4
输出
4
说明
[1,3]   [2,1]  [4],小明可以拿到4越南盾

示例3
输入
3
4 1 2
输出
0
说明
[ ]  [4, 1, 2] [ ] ,小明没办法,为了保证第一组第三组相等,只能都分成空的。所以小明只能拿到0越南盾。

import java.util.*;

public class Main {
    //贪心法,从两边向中间移动,更新maxSum
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while(input.hasNextInt()) {
            int n = input.nextInt();
            int[] nums = new int[n];
            for(int i = 0; i < n; i++) {
                nums[i] = input.nextInt();
            }
            long maxSum = 0, leftSum = 0, rightSum = 0;
            int i = -1, j = nums.length;
            //j-1==1时第二组为空,不需要再试了
            //用++i和--j使while判断时每个i和j都是已经加过的
            while(j - i > 1) {
                if(leftSum <= rightSum) {
                    leftSum += nums[++i];
                }
                else {
                    rightSum += nums[--j];
                }
                if(leftSum == rightSum) {
                    maxSum = leftSum;
                }
            }
            System.out.println(maxSum);
        }
        input.close();
    }
}

将满二叉树转换为求和树

二叉树:
                  10
                /      \
             -2        6
           /   \         /  \ 
         8    -4     7    5

求和树:
                 20(4-2+12+6)
                 /      \
           4(8-4)   12(7+5)
            /   \          /  \ 
          0      0    0    0
 

二叉树给出前序和中序输入,求和树要求中序输出;

所有处理数据不会大于int;

下面代码只通过60%,暂时还没找出原因

import java.util.*;

public class Main {
    //利用满二叉树的特性,最小子树节点为3个时为递归出口
    public static void sumTree(int[] in, int inStart, int inEnd) {
        //3个节点的树,递归出口
        if(inEnd - inStart == 2) {
            in[inStart + 1] = in[inStart] + in[inStart + 2];
            in[inStart] = 0;
            in[inStart + 2] = 0;
            return;
        }
        //否则遍历完左右子树,再求根节点
        //防溢出写法
        int root = inStart + (inEnd - inStart) / 2;
        int left = inStart + (root - 1 - inStart) / 2;
        int right = root + 1 + (inEnd - root - 1) / 2;
        //遍历之前就要改掉根节点
        in[root] = in[left] + in[right];
        
        sumTree(in, inStart, root - 1);
        sumTree(in, root + 1, inEnd);
        
        in[root] += in[left] + in[right];
    }
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while(input.hasNextInt()) {
            String[] sArr = input.nextLine().split(" ");
            int n = sArr.length;
            int[] pre = new int[n], in = new int[n];
            for(int i = 0; i < n; i++) {
                pre[i] = Integer.valueOf(sArr[i]);
            }
            for(int i = 0; i < n; i++) {
                in[i] = input.nextInt();
            }
            //将n>=3开始的交给函数处理
            if(n == 1) {
                System.out.println(in[0]);
                continue;
            }
            sumTree(in, 0, n - 1);
            for(int num : in) {
                System.out.print(num + " ");
            }
            System.out.println("");
        }
        input.close();
    }
}

 

求表达式 f(n)结果末尾0的个数

时间限制:1秒

空间限制:32768K

输入一个自然数n,求表达式 f(n) = 1!2!3!.....n! 的结果末尾有几个连续的0?

输入描述:
自然数n

输出描述:
f(n)末尾连续的0的个数

输入例子1:
11

输出例子1:
9

import java.util.*;
public class Main {
    //单个n!的结尾0个数
    public static int countZero(int n) {
        int count = 0;
        int weight = 5;
        while(n / weight != 0) {
            count += n / weight;
            weight *= 5;
        }
        return count;
    }
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while(input.hasNextInt()) {
            int n = input.nextInt();
            int count = 0;
            for(int i = 1; i <= n; i++) {
                count += countZero(i);
            }
            System.out.println(count);
        }
        input.close();
    }
}

幼儿园分班

幼儿园一个大班要分成两个小班,有些小朋友不希望自己和其他某几位小朋友同班。园长向大家收集了不希望同班的要求,然后视情况将一个大班的小朋友分成两个班。请你开发一个程序,帮助园长快速判断是否所有小朋友的不同班请求都可以被满足。

输入描述:
输入分为三部分,第一个部分是一个 int,代表这个大班里小朋友的总数。第二部分是一个 int,代表园长采集到的小朋友们的请求数。第三部分是小朋友们的请求,每个请求由两个 int 组成,第一个 int 代表提请求的小朋友,第二个 int 代表他不希望同班的另一位小朋友。

输出描述:
如果所有小朋友的请求都可以被满足,输出 1,否则输出 0。

输入例子1:
5
5
1 2
1 3
1 4
1 5
2 3

输出例子1:
0

例子说明1:
总共有 5 位小朋友,总共采集到了 5 个请求。分别是:1 不希望和 2 同班。1 不希望和 3 同班。1 不希望和 4 同班。1 不希望和 5 同班。2 不希望和 3 同班。不能满足所有人的请求,输出 0。

输入例子2:
5
4
1 2
1 3
1 4
1 5

输出例子2:
1

例子说明2:
总共有 5 位小朋友,总共采集到了 4 个请求。分别是:1 不希望和 2 同班。1 不希望和 3 同班。1 不希望和 4 同班。1 不希望和 5 同班。可以满足所有人的请求,分班方式:1 一个人一班,2、3、4、5 另一班。输出 1。

import java.util.*;
public class Main {
    //遍历两次所有请求,如果第二次遍历发现仍需调整,说明无法满足
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        while(input.hasNextInt()) {
            int n = input.nextInt();
            //用两个set代表两个班
            HashSet<Integer> set1 = new HashSet<Integer>();
            HashSet<Integer> set2 = new HashSet<Integer>();
            for(int i = 1; i <= n; i++) {
                set1.add(i);
            }
            int n2 = input.nextInt();
            int[][] request = new int[n2][2];
            for(int i = 0; i < n2; i++) {
                request[i][0] = input.nextInt();
                request[i][1] = input.nextInt();
                if(set1.contains(request[i][0]) && set1.contains(request[i][1])) {
                    set1.remove(request[i][1]);
                    set2.add(request[i][1]);
                }
                else if(set2.contains(request[i][0]) && set2.contains(request[i][1])) {
                    set2.remove(request[i][1]);
                    set1.add(request[i][1]);
                }
            }
            int i = 0;
            for(; i < n2; i++) {
                //分班失败
                if(set1.contains(request[i][0]) && set1.contains(request[i][1])
                  || set2.contains(request[i][0]) && set2.contains(request[i][1])) {
                    System.out.println("0");
                    break;
                }
            }
            //成功分班
            if(i == n2) {
                System.out.println("1");
            }
        }
    }
}

小米第一题,括号构建二叉树,输出中序遍历

例:1(2(3,4(,5)),6(7,))         输出:3245176

import java.io.*;
import java.util.*;

public class Main {

    static class TreeNode {
        String val;
        TreeNode left;
        TreeNode right;
        public TreeNode(String val) {
            this.val = new String(val);
        }
    }

    static String solution(String input) {
        if(input == null) {
            return null;
        }
        TreeNode root = generateTree(input);
        StringBuilder res = new StringBuilder();
        inOrder(root, res);
        return res.toString();
    }

    static TreeNode generateTree(String input) {
        if(input.equals("")) {
            return null;
        }
        while (input.startsWith("(")) {
            input = input.substring(1, input.length() - 1);
        }
        if(input.indexOf('(') < 0) {
            return new TreeNode(input);
        }

        int leftStart = input.indexOf('(') + 1;
        int leftEnd = leftStart;
        TreeNode root = new TreeNode(input.substring(0, leftStart - 1));

        int count = 0;  
        for(int i = leftStart; i < input.length() - 1; i++) {
            if(input.charAt(i) == ',' && count == 0) {
                leftEnd = i;
                break;
            }
            else if(input.charAt(i) == '(') {
                count++;
            }
            else if(input.charAt(i) == ')') {
                count--;
            }
        }
        root.left = generateTree(input.substring(leftStart, leftEnd));
        root.right = generateTree(input.substring(leftEnd + 1, input.length() - 1));
        return root;
    }

    static void inOrder(TreeNode root, StringBuilder res) {
        if(root == null) {
            return;
        }
        inOrder(root.left, res);
        res.append(root.val);
        inOrder(root.right, res);
    }
}

网易互娱第二批笔试

1.二进制回文数

import java.util.Scanner;
public class Main {
    public static boolean isPandNum(int num) {
        if((num & 1) == 0) {
            return false;
        }
        int i = 30;
        for(; i >= 0; i--) {
            if(((num >> i) & 1) > 0) {
                break;
            }
        }
        int j = 0;
        while(i > j) {
            if(((num >> i) & 1) != ((num >> j) & 1)) {
                return false;
            }
            else {
                i--;
                j++;
            }
        }
        return true;
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while(in.hasNextInt()) {
            int t = in.nextInt();
            boolean[] res = new boolean[t];
            for(int i = 0; i < t; i++) {
                res[i] = isPandNum(in.nextInt());
            }
            for(int i = 0; i < t; i++) {
                if(res[i]) {
                    System.out.println("YES");
                }
                else {
                    System.out.println("NO");
                }
            }
        }
    }
}

2.按编号顺序给定树节点val、left编号、right编号,,1为null,每行3个值,输出是否是递增树,即每层val之和严格递增

import java.util.ArrayList;
import java.util.Scanner;
public class Main {
    public static class TreeNode {
        public int val;
        public TreeNode left;
        public TreeNode right;
        public boolean isRoot = true;
    }
    public static boolean increTree(TreeNode root) {
        ArrayList<Integer> sums = new ArrayList<>();
        preOrder(root, 0, sums);
        for(int i = 1; i < sums.size(); i++) {
            if(sums.get(i) <= sums.get(i - 1)) {
                return false;
            }
        }
        return true;
    }
    public static void preOrder(TreeNode root, int depth, ArrayList<Integer> sums) {
        if(root == null) {
            return;
        }
        if(sums.size() == depth) {
            sums.add(root.val);
        }
        else {
            sums.set(depth, sums.get(depth) + root.val);
        }
        preOrder(root.left, depth + 1, sums);
        preOrder(root.right, depth + 1, sums);
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while(in.hasNextInt()) {
            int t = in.nextInt();
            boolean[] res = new boolean[t];
            for(int i = 0; i < t; i++) {
                int n = in.nextInt();
                TreeNode[] arr = new TreeNode[n];
                for(int j = 0; j < n; j++) {
                    arr[j] = new TreeNode();
                }
                for(int j = 0; j < n; j++) {
                    arr[j].val = in.nextInt();
                    int left = in.nextInt();
                    int right = in.nextInt();
                    if(left != -1) {
                        arr[j].left = arr[left];
                        arr[left].isRoot = false;
                    }
                    if(right != -1) {
                        arr[j].right = arr[right];
                        arr[right].isRoot = false;
                    }
                }
                for(int j = 0; j < n; j++) {
                    if(arr[j].isRoot) {
                        res[i] = increTree(arr[j]);
                        break;
                    }
                }
            }
            for(int i = 0; i < t; i++) {
                if(res[i]) {
                    System.out.println("YES");
                }
                else {
                    System.out.println("NO");
                }
            }
        }
    }
}

3.一个月30天,给定连续两天喝咖啡的最小间隔天数k,以及m个确定会喝的天,求最多喝多少天(在k和m个给定值的限制下最多再插入多少天,再加上m)

import java.util.Scanner;
public class Main {
    public static int maxInsert(int a, int b, int k) {
        if(a == 0) {
            return (b - k - 1 + k) / (1 + k);
        }
        if(b == 31) {
            return (30 - a - k + k) / (1 + k);
        }
        int count = 0;
        for(int i = a + k + 1; i < b - k; i += k + 1) {
            count++;
        }
        return count;
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while(in.hasNextInt()) {
            int t = in.nextInt();
            int[] res = new int[t];
            for(int i = 0; i < t; i++) {
                int k = in.nextInt();
                int m = in.nextInt();
                if(m == 0) {
                    res[i] = (30 + k) / (1 + k);
                    continue;
                }
                res[i] = m;
                int a = 0, b = 0;
                for(int j = 0; j < m; j++) {
                    b = in.nextInt();
                    res[i] += maxInsert(a, b, k);
                    a = b;
                }
                res[i] += maxInsert(b, 31, k);
            }
            for(int i = 0; i < t; i++) {
                System.out.println(res[i]);
            }
        }
    }
}

4.给定01矩阵,求最大十字旗左上和右下坐标同样大的取最左上(十字旗:3x3一共9个正方形,24568为全1,其余全0)

 

VIVO 9.11笔试

2.二维01背包

给定一台服务器磁盘和内存大小,以及一组程序,每个程序已知需要的磁盘和内存、用户数,每个程序只能部署一次,求最大可得的用户数

import java.io.*;
import java.util.*;

/**
 * Welcome to vivo !
 */

public class Main {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String inputStr = br.readLine();
        String[] input = inputStr.split(" ");
        int totalDisk = Integer.parseInt(input[0]);
        int totalMemory = Integer.parseInt(input[1]);
        List<Service> services = parseServices(input[2].split("#"));
        int output = solution(totalDisk, totalMemory, services);
        System.out.println(output);
    }

    private static int solution(int totalDisk, int totalMemory, List<Service> services) {

        // TODO Write your code here
        int n = services.size();
        int[][][] dp = new int[n + 1][totalDisk + 1][totalMemory + 1];
        for(int i = 1; i <= n; i++ ) {
            for(int j = 1; j <= totalDisk; j++) {
                for (int k = 1; k <= totalMemory; k++) {
                    if(services.get(i - 1).disk > j || services.get(i - 1).memory > k) {
                        dp[i][j][k] = dp[i - 1][j][k];
                    }
                    else {
                        dp[i][j][k] = Math.max(dp[i - 1][j][k], dp[i - 1][j - services.get(i - 1).disk][k - services.get(i - 1).memory] + services.get(i - 1).users);
                    }
                }
            }
        }
        return dp[n][totalDisk][totalMemory];
    }

    private static List<Service> parseServices(String[] strArr) {
        if (strArr == null || strArr.length == 0) {
            return new ArrayList<Service>(0);
        }
        List<Service> services = new ArrayList<>(strArr.length);
        for (int i = 0; i < strArr.length; i++) {
            String[] serviceArr = strArr[i].split(",");
            int disk = Integer.parseInt(serviceArr[0]);
            int memory = Integer.parseInt(serviceArr[1]);
            int users = Integer.parseInt(serviceArr[2]);
            services.add(new Service(disk, memory, users));
        }
        return services;
    }

    static class Service {
        private int disk;

        private int memory;

        private int users;

        public Service(int disk, int memory, int users) {
            this.disk = disk;
            this.memory = memory;
            this.users = users;
        }

        public int getDisk() {
            return disk;
        }

        public void setDisk(int disk) {
            this.disk = disk;
        }

        public int getMemory() {
            return memory;
        }

        public void setMemory(int memory) {
            this.memory = memory;
        }

        public int getusers() {
            return users;
        }

        public void setusers(int users) {
            this.users = users;
        }
    }
}

58集团9.13笔试

2. 发饼干,输入数组代表每个小朋友的分数,要求每个人和相邻左右两个的分数比较,相邻分数低的饼干数要少于分数高的;

没人至少发一个饼干,求最少要准备多少个饼干

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while(in.hasNext()) {
            int n = in.nextInt();
            int[] scores = new int[n];
            for(int i = 0; i < n; i++) {
                scores[i] = in.nextInt();
            }
            int[] cakes = new int[n];
            //初始化全1
            Arrays.fill(cakes, 1);
            for(int i = 1; i < n; i++) {
                //每个位置默认前面是最优解,则当前位置比前一个大的时候+1
                if(scores[i] > scores[i - 1]) {
                    cakes[i] = cakes[i - 1] + 1;
                }
                //否则当前位置比前一个小的时候,只有前一个为1时需要处理(前一个不为1时当前默认1即可)
                else if(cakes[i - 1] == 1) {
                    for(int j = i - 1; j >= 0; j--) {
                        if(scores[j] > scores[j + 1] && cakes[j] <= cakes[j + 1]) {
                            cakes[j] = cakes[j + 1] + 1;
                            //System.out.println("cakes  " + i + " = " + cakes[i]);
                        }
                        if(j > 0 && scores[j] < scores[j - 1] && cakes[j] < cakes[j - 1]) {
                            break;
                        }
                    }
                }

            }
            int sum = 0;
            for(int num : cakes) {
                sum += num;
            }
            System.out.print(sum);
        }
    }
}

3.输入矩阵权值,求左上到右下最小权值路径。(简单动态规划)

import java.util.Scanner;

public class Main3 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int m = in.nextInt(), n = in.nextInt();
            int[][] weights = new int[m][n];
            for(int i = 0; i < m; i++) {
                for(int j = 0; j < n; j++) {
                    weights[i][j] = in.nextInt();
                    if(i == 0 && j == 0) {
                        continue;
                    }
                    else if(i == 0) {
                        weights[0][j] += weights[0][j - 1];
                    }
                    else if(j == 0) {
                        weights[i][0] += weights[i - 1][0];
                    }
                    else {
                        weights[i][j] += Math.min(weights[i - 1][j], weights[i][j - 1]);
                    }
                }
            }
            System.out.print(weights[m - 1][n - 1]);
        }
    }
}

VipKid 9.16笔试第2题,整数拆分成多个数之和,输出所有结果

例如输入:

4

输出:

1+1+1+1

1+1+2

1+3

2+2

4

import java.util.Arrays;
import java.util.Scanner;

public class Main2 {
    public static String fun(int t) {
        StringBuilder res = new StringBuilder();
        int[] arr = new int[t];
        Arrays.fill(arr, 1);
        int sum = t;
        int index = t - 1;
        while(arr[0] != 0) {
            if(sum == t) {
                for(int j = 0; j < index; j++) {
                    res.append(arr[j] + "+");
                }
                res.append(arr[index] + "\n");
                sum -= arr[index];
                arr[index] = 0;
                index--;
                if(index >= 0) {
                    arr[index]++;
                    sum++;
                }
                continue;
            }
            if(sum < t) {
                arr[index + 1] = arr[index];
                sum += arr[index + 1];
                index++;
                continue;
            }
            else {
                sum -= arr[index];
                if(index - 1 >= 0) {
                    arr[index - 1]++;
                    sum++;
                }
                index--;
            }
        }
        return res.toString();
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while(in.hasNext()) {
            int t = in.nextInt();
            System.out.print(fun(t));
        }
    }
}

9.21 网易笔试

3. 最大和上升子序列(每个元素 >= 前面所有元素的和)

写完感觉逻辑没问题,不知道为什么一直0%

import java.util.Scanner;

public class Main {
    public static int fun(long[] nums, int n) {
        int[] dp = new int[n];
        long[] sum = new long[n];
        dp[0] = 1;
        sum[0] = nums[0];
        int max = 1;
        for(int i = 1; i < n; i++) {
            dp[i] = 1;
            sum[i] = nums[i];
            for(int j = 0; j < i; j++) {
                if(sum[j] <= nums[i]) {
                    if(dp[j] + 1 > dp[i]) {
                        dp[i] = dp[j] + 1;
                        sum[i] = sum[j] + nums[i];
                    }
                    else if(dp[j] + 1 == dp[i] && sum[i] > sum[j] + nums[i]) {
                        sum[i] = sum[j] + nums[i];
                    }
                }
            }
            max = Math.max(max, dp[i]);
        }
        return max;
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int t = in.nextInt();
            int[] res = new int[t];
            for (int i = 0; i < t; i++) {
                int n = in.nextInt();
                if(n == 0) {
                    res[i] = 0;
                    continue;
                }
                long[] nums = new long[n];
                for (int j = 0; j < n; j++) {
                    nums[j] = (long) in.nextInt();
                }
                res[i] = fun(nums, n);
            }
            for (int i = 0; i < t; i++) {
                System.out.println(res[i]);
            }
        }
    }
}


4. 求1-n的乱序数组逆序距离和

没想到最优解法,只会暴力

import java.util.Scanner;

public class Main4 {
    public static int fun(int[] nums, int n) {
        int sum = 0;
        for (int i = 1; i < n; i++) {
            for (int j = i - 1; j >= 0; j--) {
                if(nums[j] > nums[i]) {
                    sum += nums[j] - nums[i];
                }
            }
        }
        return sum;
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int n = in.nextInt();
            int[] nums = new int[n];
            for(int i = 0; i < n; i++) {
                nums[i] = in.nextInt();
            }
            System.out.println(fun(nums, n));
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值