网易

1. 找工作

为了找到自己满意的工作,牛牛收集了每种工作的难度和报酬。牛牛选工作的标准是在难度不超过自身能力值的情况下,牛牛选择报酬最高的工作。在牛牛选定了自己的工作后,牛牛的小伙伴们来找牛牛帮忙选工作,牛牛依然使用自己的标准来帮助小伙伴们。牛牛的小伙伴太多了,于是他只好把这个任务交给了你。

思路:暴力法超时, 用HashMap存储

import java.util.*;
 
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int[] t = new int[n + m];
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < n; i++) {
            t[i] = scanner.nextInt();
            map.put(t[i], scanner.nextInt());
        }
        int[] t2 = new int[m];
        for (int i = 0; i < m; i++) {
            t[n+i]=scanner.nextInt();
            t2[i] = t[n+i];
        }
        scanner.close();
        Arrays.sort(t);
        
        int max = 0;
        for (int i = 0; i < n + m; i++) {
            max = Math.max(map.getOrDefault(t[i],0),max);
            map.put(t[i],max);
        }

        for (int i = 0; i < m; i++) System.out.println(map.get(t2[i]));
    }
}

  

2. 数对

牛牛以前在老师那里得到了一个正整数数对(x, y), 牛牛忘记他们具体是多少了。

但是牛牛记得老师告诉过他x和y均不大于n, 并且x除以y的余数大于等于k。

牛牛希望你能帮他计算一共有多少个可能的数对。

思路:y确定时候 x可以取2种

  • 第一种  k,k+1,k+2...,y-1;  y+k,y+k+1,...,2y-1;    ...  ...my-1; 
  • 第二种   my+k,my+k+1,..., my+k+t=n

第一种共(n/y)组,每组从 my+k 到 (m+1)y-1,即每组 y-k个;  共 (n/y)*([(m+1)y-1]  -  [my+k ] +1) = (n/y)*(y- k)

第二种当 n%y数大于等于k时候存在,共 n%y - (k-1)个, 即 Math.max(0, n%y - k+1)

import java.util.*;
 
/**
 * @author zzm
 * @data 2020/5/23 17:09
 */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        long n = scanner.nextInt();
        long k = scanner.nextInt();
        long res = 0;
        if(k==0) {
            System.out.println(n*n);
            return;
        }
        for (long y = k+1; y <= n; y++) {
            //y确定时候 x可以取 (n/y)组,每组从 my+k 到 (m+1)y-1,即每组 y-k个
            res += (n/y)*(y-k) + Math.max(0,n%y-k+1);
        }
        System.out.println(res);
    }
}

  

3. 被3整除

小Q得到一个神奇的数列: 1, 12, 123,...12345678910,1234567891011...。

并且小Q对于能否被3整除这个性质很感兴趣。

小Q现在希望你能帮他计算一下从数列的第l个到第r个(包含端点)有多少个数可以被3整除。

输入描述:

输入包括两个整数l和r(1 <= l <= r <= 1e9), 表示要求解的区间两端。
思路:每相邻三个数中有两个可以被整除
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){

            int l = scanner.nextInt();
            int r = scanner.nextInt();
            System.out.println(cal(r)-cal(l-1));
        }
        scanner.close();
    }

    private static int cal(int num) {
        int res = num / 3 * 2;
        res += (num % 3 == 2) ? 1 : 0;
        return res;
    }
}

4. 最大矩阵重叠数

平面内有n个矩形, 第i个矩形的左下角坐标为(x1[i], y1[i]), 右上角坐标为(x2[i], y2[i])。

如果两个或者多个矩形有公共区域则认为它们是相互重叠的(不考虑边界和角落)。

请你计算出平面内重叠矩形数量最多的地方,有多少个矩形相互重叠。

输入描述:
输入包括五行。
第一行包括一个整数n(2 <= n <= 50), 表示矩形的个数。
第二行包括n个整数x1[i](-10^9 <= x1[i] <= 10^9),表示左下角的横坐标。
第三行包括n个整数y1[i](-10^9 <= y1[i] <= 10^9),表示左下角的纵坐标。
第四行包括n个整数x2[i](-10^9 <= x2[i] <= 10^9),表示右上角的横坐标。
第五行包括n个整数y2[i](-10^9 <= y2[i] <= 10^9),表示右上角的纵坐标。
思路: A分别和B C重叠,但是B C不重叠的时候只算2个而不是3个
遍历判断 :重叠区域必为一矩形, 重叠区域的四个顶点都为输入矩形的顶点。 判断包含某个顶点的最大矩形数
import java.util.*;
import static java.lang.Math.*;
/**
 * @author zzm
 * @data 2020/5/23 17:34
 */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] x1 = new int[n];
        int[] y1 = new int[n];
        int[] x2 = new int[n];
        int[] y2 = new int[n];
        for (int i = 0; i < n; i++) x1[i] = scanner.nextInt();
        for (int i = 0; i < n; i++) y1[i] = scanner.nextInt();
        for (int i = 0; i < n; i++) x2[i] = scanner.nextInt();
        for (int i = 0; i < n; i++) y2[i] = scanner.nextInt();
        scanner.close();

        ArrayList<Integer> X = new ArrayList<>();
        Arrays.stream(x1).forEach(a -> X.add(a));
        Arrays.stream(x2).forEach(a -> X.add(a));

        ArrayList<Integer> Y = new ArrayList<>();
        Arrays.stream(y1).forEach(a -> Y.add(a));
        Arrays.stream(y2).forEach(a -> Y.add(a));

        int res = 1;

        for (int x : X) {
            for (int y : Y) {
                int now = 0;
                for (int i = 0; i < n; i++) {
                    if (x < x2[i] && x >= x1[i] && y < y2[i] && y >= y1[i]) now++;
                }
                res = Math.max(res, now);
            }
        }
        System.out.println(res);
    }
}

5. 上学的最晚时间

牛牛总是睡过头,所以他定了很多闹钟,只有在闹钟响的时候他才会醒过来并且决定起不起床。从他起床算起他需要X分钟到达教室,上课时间为当天的A时B分,请问他最晚可以什么时间起床
输入描述:
每个输入包含一个测试用例。
每个测试用例的第一行包含一个正整数,表示闹钟的数量N(N<=100)。
接下来的N行每行包含两个整数,表示这个闹钟响起的时间为Hi(0<=A<24)时Mi(0<=B<60)分。
接下来的一行包含一个整数,表示从起床算起他需要X(0<=X<=100)分钟到达教室。
接下来的一行包含两个整数,表示上课时间为A(0<=A<24)时B(0<=B<60)分。
数据保证至少有一个闹钟可以让牛牛及时到达教室。
输出描述:
输出两个整数表示牛牛最晚起床时间。
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

/**
 * @author zzm
 * @data 2020/5/23 18:12
 */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[][] clocks = new int[n][2];
        for (int i = 0; i < n; i++) {
            clocks[i][0] = scanner.nextInt();
            clocks[i][1] = scanner.nextInt();
        }
        int totle = scanner.nextInt();
        int h = scanner.nextInt();
        int m = scanner.nextInt();
        Arrays.sort(clocks, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                if(o1[0]==o2[0]) return o2[1]-o1[1];
                else return o2[0]-o1[0];
            }
        });

        for (int i = 0; i < n; i++) {
            if (helper(clocks[i][0], clocks[i][1], h, m) >= totle) {
                System.out.println(clocks[i][0] + " " + clocks[i][1]);
                break;
            }
        }
    }

    private static int helper(int h1, int m1, int h2, int m2) {
            return (h2 - h1) * 60 + (m2 - m1);
    }
}

6. 背包问题

牛牛准备参加学校组织的春游, 出发前牛牛准备往背包里装入一些零食, 牛牛的背包容量为w。
牛牛家里一共有n袋零食, 第i袋零食体积为v[i]。
牛牛想知道在总体积不超过背包容量的情况下,他一共有多少种零食放法(总体积为0也算一种放法)。
输入描述:
输入包括两行
第一行为两个正整数n和w(1 <= n <= 30, 1 <= w <= 2 * 10^9),表示零食的数量和背包的容量。
第二行n个正整数v[i](0 <= v[i] <= 10^9),表示每袋零食的体积。
输出描述:
输出一个正整数, 表示牛牛一共有多少种零食放法。
思路:此题背包容量过大,不能用动态规划
import java.util.*;

public class Main {
    static int res = 0;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        long cap = scanner.nextLong();
        long[] w = new long[n];
        long totle = 0;
        for (int i = 0; i < n; i++) {
            w[i] = scanner.nextLong();
            totle += w[i];
        }
        if (totle <= cap) System.out.println((int)Math.pow(2, n));
        else {
           helper(0, n, 0, w, cap);
            System.out.println(res);
        }
    }

    private static void helper(int i, int n, long sum, long[] w, long cap) {
        if (i >= n) {
            if (sum <= cap) res++;
            return;
        }
        if (sum > cap) return;
        helper(i + 1, n, sum + w[i], w, cap);
        helper(i + 1, n, sum, w, cap);
    }
}
posted @ 2020-05-24 21:43  zzmhust  阅读(178)  评论(0编辑  收藏  举报