网易
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); } }