hulu笔试3.15 通过了2.8
1
// 本题为考试单行多行输入输出规范示例,无需提交,不计分。 import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int[] nums = new int[n]; for (int i = 0; i < n; i++) { nums[i] = scanner.nextInt(); } int res = fun(nums); } private static int fun(int[] nums) { int res = 0; for (int i = 0; i < nums.length; i++) { if (nums[i] == -1) { continue; } int left = i * 2 - 1, right = i * 2; boolean l = left >= nums.length || nums[left] == -1; boolean r = right >= nums.length || nums[right] == -1; if (l && r) { res ++; } } return res; } }
2
// 本题为考试单行多行输入输出规范示例,无需提交,不计分。 import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int m = scanner.nextInt(); int n = scanner.nextInt(); scanner.nextLine(); char[][] matrix = new char[m][n]; for (int i = 0; i < m; i++) { String str = scanner.nextLine(); for (int j = 0; j < n; j++) { matrix[i][j] = str.charAt(j); } } int a = scanner.nextInt(); int b = scanner.nextInt(); scanner.nextLine(); char[][] image = new char[a][b]; for (int i = 0; i < a; i++) { String str = scanner.nextLine(); for (int j = 0; j < b; j++) { image[i][j] = str.charAt(j); } } int res = fun(matrix, image); System.out.println(res); } private static int fun(char[][] matrix, char[][] image) { int n = matrix.length; int m = matrix[0].length; int a = image.length; int b= image[0].length; int res = 0; for (int i = 0; i <= n - a; i++) { for (int j = 0; j <= m - b; j++) { if (isValid(matrix, image, i, j)) { res ++; } } } return res; } private static boolean isValid(char[][] matrix, char[][] image, int i, int j) { int a = image.length; int b= image[0].length; for (int p = 0; p < a; p++) { for (int q = 0; q < b; q++) { if (matrix[i + p][j + q] != image[p][q]) { return false; } } } return true; } }
3
暴力O(N^2)只过了82%
// 本题为考试单行多行输入输出规范示例,无需提交,不计分。 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(); long k = scanner.nextLong(); long[] nums = new long[n]; for (int i = 0; i < n; i++) { nums[i] = scanner.nextLong(); } long res = fun1(nums, m, k); System.out.println(res); } private static long fun1(long[] nums, int m, long k) { int len = nums.length; long res = 0; for (int i = 0; i < len; i++) { long sum = 0; int negatives = 0; for (int j = i; j < len; j++) { sum += nums[j]; // [i, j] if (nums[j] < 0) { negatives ++; } if (negatives > m) { break; } if (sum > k) { continue; } res = Math.max(res, sum); if (res == k) { return k; } } } return res; } }尝试将上面的复杂度降低为O(NlogN),测试用例通过了,不知道是否正确。参考 https://blog.csdn.net/u010900754/article/details/60457594
// 本题为考试单行多行输入输出规范示例,无需提交,不计分。 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(); long k = scanner.nextLong(); long[] nums = new long[n]; for (int i = 0; i < n; i++) { nums[i] = scanner.nextLong(); } long res = fun(nums, m, k); System.out.println(res); } /** * 计算负数个数不超过m,总收益不超过k的最大子数组和 * @param nums * @param m * @param k * @return */ private static long fun(long[] nums, int m, long k) { int len = nums.length; // [i] [0,i-1]之间的子数组和 long[] preSum = new long[len + 1]; for (int i = 0; i < nums.length; i++) { preSum[i + 1] = preSum[i] + nums[i]; } long res = 0; TreeMap<Long, Integer> treeMap = new TreeMap<>(); int l = 0, r = 0; int negatives = 0; treeMap.put(0L, 0); while (r < len){ // 更新r的信息 if (nums[r] < 0) { negatives ++; } treeMap.put(preSum[r + 1], r); while (negatives > m) { if (nums[l] < 0) { negatives --; } if (treeMap.get(nums[l]) == l) { treeMap.remove(nums[l]); } l ++; } // [l, r]中负数<=m Map.Entry<Long, Integer> entry = treeMap.ceilingEntry(preSum[r + 1] - k); res = Math.max(res, preSum[r + 1] - entry.getKey()); r ++; } return res; } }