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

浙公网安备 33010602011771号