具体题的内容站内自行搜索-华为od机试真题2023
这里不贴链接了,防止侵权什么的
除了最后3个经过验证,其他的不保证全通过率
只是自己随便写了些题目的答案,有些是在别人专栏内不足100%的基础上优化的,自行斟酌吧
都是打工的兄弟,就不开专栏了,准备期间的题答案都贡献出来,一把梭哈
1.统一限载货物数最小值
private static void minGoods() {
Scanner sc = new Scanner(System.in);
int len = sc.nextInt();
int[] arr = new int[len];
for (int i = 0; i < len; i++) {
arr[i] = sc.nextInt();
}
List<Integer> wetGoods = new LinkedList<>();
List<Integer> dryGoods = new LinkedList<>();
int drySum = 0, wetSum = 0;
for (int i = 0; i < len; i++) {
int temp = sc.nextInt();
if (temp == 0) {
dryGoods.add(arr[i]);
drySum += arr[i];
} else {
wetGoods.add(arr[i]);
wetSum += arr[i];
}
}
int k = sc.nextInt();
// 本质是求k量车,容量最小是多少时,可以装下所有货物
int min = Math.max(dryGoods.size() != 0 ? drySum / dryGoods.size() : 0,wetGoods.size() != 0 ? wetSum / wetGoods.size() : 0);
int max = Math.max(drySum, wetSum);
int res = max;
while (min <= max) {
int mid = (min + max) / 2;
if (judgeVolume(mid, k, dryGoods, wetGoods, drySum, wetSum)) {// 可以放得下
res = mid;
max = mid - 1;
} else {
min = mid + 1;
}
}
System.out.println(res);
}
// vol的容量,能不能装下这些货物
private static boolean judgeVolume(int vol, int k, List<Integer> dryGoods, List<Integer> wetGoods, int drySum, int wetSum) {
Collections.sort(dryGoods);
Collections.sort(wetGoods);
int drySize = dryGoods.size();
int wetSize = wetGoods.size();
if (drySize > 0 && vol < dryGoods.get(drySize - 1)) return false;
if (wetSize > 0 && vol < wetGoods.get(wetSize - 1)) return false;
Set<Integer> dryIndex = new HashSet<>();
for (int i = 0; i < k && drySum > 0; i++) {
int temp = vol;
for (int j=drySize-1;j>=0 && temp > 0;j--){
int good = dryGoods.get(j);
if(!dryIndex.contains(j) && good >= 0 && good <= temp){
temp -= good;
drySum -= good;
dryIndex.add(j);
}
}
}
Set<Integer> wetIndex = new HashSet<>();
for (int i = 0; i < k && wetSum > 0; i++) {
int temp = vol;
for (int j=wetSize-1;j>=0 && temp > 0;j--){
int good = wetGoods.get(j);
if(!wetIndex.contains(j) && good >= 0 && good <= temp){
temp -= good;
wetSum -= good;
wetIndex.add(j);
}
}
}
return drySum == 0 && wetSum == 0;
}
2.几何平均值最大子数组
private static void maxSub() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int l = sc.nextInt();
double[] nums = new double[n];
for (int i = 0; i < n; i++) {
// nums[i] = random.nextInt(20);
nums[i] = sc.nextDouble();
}
System.out.println(Arrays.toString(nums));
// 暴力做法,复杂度n2,也就是10^10
double max = 0;
int lIndex = -l - 1;
int rIndex = 0;
for (int i = 0; i < n - l + 1; i++) {
double mul = 1;
double tem;
for (int j = i; j < n; j++) {
mul = mul * nums[j];
if (j - i + 1 < l) continue;
tem = Math.pow(mul, (double) 1 / (j - i + 1));
// 相等
if (tem - max > 0.000001) {
max = tem;
lIndex = i;
rIndex = j;
}
}
}
System.out.println(lIndex + " " + (rIndex - lIndex + 1) + " " + max);
}
3.士兵过河
/**
* 1:1个士兵过河,用时t1
* 2:2个士兵过河,用时t_max
* 3:3个士兵过河,用时10 * t_min
* <p>
* 多个士兵时,最少俩士兵一起,因为用时短的不算时间
* 如果3个士兵,那肯定是2个用时最长的配一个用时最短的,且满足三人用时最短
* 6个士兵,如何渡河?
*/
private static void soldierRiver() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int t = sc.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
String s = crossTheRiver(n, t, arr);
System.out.println(s);
}
// 返回最多存活士兵+最短用时
/**
* 说明
* 0 1 2 3 4 5 6 7 8
* 12 13 15 20 20 25 35 99 99
* dp[0] = 12
* dp[1] = 13
* dp[2] = 15+12+13 = 40
* dp[3] = 13 + 12 + 20 + 13 * 2 = 71
* dp[4] = 103 / 40 + 12 + 20 + 26 = 98
* dp[5] = 98 + 37 = 135 / 71 + 12 + 25 + 26 = 134
* dp[6] = 134 + 47 = 181 / 98 + 12 + 35 + 26 = 171
* dp[7] = 171 + 111 = 282 / 134 + 12 + 99 + 26 = 271 / 134 + 12 + 120 = 266
* dp[8] = 266 + 111 = 377 / 171 + 12 + 99 + 26 = 308 / 171 + 12 + 120 = 303
*/
public static String crossTheRiver(int n, int t, int[] a) {
Arrays.sort(a);
if (a[0] > t) {
return "0 0";
}
// 士兵数小于 2
if (n < 2) {
return "1 " + a[0];
}
int[] dp = new int[n];
dp[0] = a[0];
dp[1] = a[1];
if (dp[1] > t) {
return "1 " + dp[0];
}
for (int i = 2; i < n; i++) {
int a1 = dp[i - 1] + a[0] + Math.max(a[0], a[i]);
// a[0]和a[1]得开回来
int a2 = dp[i - 2] + a[0] + Math.max(a[i - 1], a[i]) + 2 * a[1];
if (10 * a[0] < a2 - dp[i - 2] - a[0]) a2 = dp[i - 2] + a[0] + 10 * a[0];
dp[i] = Math.min(a1, a2);
if (dp[i] > t) {
//System.out.println(Arrays.toString(dp));
return i + " " + dp[i - 1];
}
}
//System.out.println(Arrays.toString(dp));
return n + " " + dp[n - 1];
}
4.任务混部/最少服务器数
private static void taskDeploy() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] nums = new int[n][3];
for (int i = 0; i < n; i++) {
nums[i][0] = sc.nextInt();
nums[i][1] = sc.nextInt();
nums[i][2] = sc.nextInt();
}
int res = 0;
for (int i = 0; i < n; i++) {
int timeStart = nums[i][0];
int timeEnd = nums[i][1];
int temp = 0;
for (int j = 0; j < n; j++) {
if (!(nums[j][0] >= timeEnd || nums[j][1] < timeStart)) {
temp += nums[j][2];
}
}
res = Math.max(temp, res);
}
System.out.println(res);
}
5.垃圾短信发送者
private static void garbageText() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] texts = new int[n][2];
for (int i = 0; i < n; i++) {
texts[i][0] = sc.nextInt();
texts[i][1] = sc.nextInt();
}
int id = sc.nextInt();
// in:接收短信数量 out:发送短信数量 mapDiff:A发送给x和接收x短信的差值
int in = 0;
int out = 0;
Map<Integer, Integer> mapDiff = new HashMap<>();
Set<Integer> sets = new HashSet<>();
for (int i = 0; i < n; i++) {
int startId = texts[i][0];
int endId = texts[i][1];
if (startId == id) {
out++;
Integer nums = mapDiff.getOrDefault(endId, 0);
mapDiff.put(endId, nums + 1);
}
if (endId == id) {
in++;
Integer nums = mapDiff.getOrDefault(startId, 0);
mapDiff.put(startId, nums - 1);
sets.add(startId);// 发送过短信给A的id
}
}
int diff = out - in;
int sizeDiff = mapDiff.size() - sets.size();
if (diff > 10 || sizeDiff > 5) {
System.out.println("true " + sizeDiff + " " + diff);
return;
}
for (Integer val : mapDiff.values()) {
if (val > 5) {
System.out.println("true " + sizeDiff + " " + diff);
return;
}
}
System.out.println("false " + sizeDiff + " " + diff);
}
6.信号发射和接收
private static void singleLine() {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
int[][] matrix = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = sc.nextInt();
}
}
/**
* 分析
* 只能接受左边或者上边来的信号
* 左边第一个不小于自己高的天线 +(左边声明一个最大高度,不断遍历时迭代,低于这个高度的不统计,大于等于的更新高度和累加信号数)
*/
// 东西向
int[][] row = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int index = j - 1;
int tempMax = 0;
int nums = 0;
while (index >= 0 && matrix[i][index] < matrix[i][j]) {
if (matrix[i][index] > tempMax) {
nums++;
tempMax = matrix[i][index];
}
index--;
}
if (index >= 0 && matrix[i][index] >= matrix[i][j]) nums++;
row[i][j] = nums;
}
}
// 南北向
int[][] col = new int[m][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int index = j - 1;
int tempMax = 0;
int nums = 0;
while (index >= 0 && matrix[index][i] < matrix[j][i]) {
if (matrix[index][i] > tempMax) {
nums++;
tempMax = matrix[index][i];
}
index--;
}
if (index >= 0 && matrix[index][i] == matrix[j][i]) nums++;
col[j][i] = nums;
}
}
System.out.println(m + " " + n);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = row[i][j] + col[i][j];
System.out.print(matrix[i][j]);
if (i != m - 1 || j != n - 1) {
System.out.print(" ");
}
}
}
}
7.红黑图—将不合格的剔除即可行
private static void redBlackGraph() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();// nodes num
int m = sc.nextInt();// edge num
List<int[]> edges = new LinkedList<>();
for (int i = 0; i < m; i++) {
int s = sc.nextInt();
int e = sc.nextInt();
int[] edge = {s, e};
edges.add(edge);
}
int allPath = (int) Math.pow(2, n);
int res = allPath;
for (int i = 0; i < allPath; i++) {
// 规定1红,0黑
for (int[] edge : edges) {
int start = 1 << edge[0];
int end = 1 << edge[1];
if ((start & i) != 0 && (end & i) != 0) {
res--;
break;
}
}
}
System.out.println(res);
}
8.linux发行版的数量
private static void linuxNums() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] nums = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
nums[i][j] = sc.nextInt();
}
}
int max = 0;
Set<Integer> maxIndes = new HashSet<>();
for (int i = 0; i < n && !maxIndes.contains(i); i++) {
Set<Integer> visited = new HashSet<>();
Deque<Integer> deque = new LinkedList<>();
deque.addLast(i);
while (!deque.isEmpty()) {
int index = deque.pollFirst();
visited.add(index);
for (int j = 0; j < n; j++) {
if (nums[index][j] == 1 && !visited.contains(j)) {
deque.addLast(j);
}
}
}
if (visited.size() > max) {
max = visited.size();
maxIndes = visited;
}
}
System.out.println(max);
}
9.天然蓄水库
目前样例全过
// 1 2 3---0
// 1 9 6 2 5 4 9 3 7---1 6:19
// 1 8 6 2 5 4 8 3 7---1 6:15
// 1 7 3 10 10---1 3:4
// 4 3 2 0 2 3---1 5:5
// 1 2 2 0 2 1 2 0 2 2---2 8:5
private static void natureWater() {
Scanner sc = new Scanner(System.in);
String arr = sc.nextLine();
String[] s = arr.split(" ");
int[] nums = new int[s.length];
nums[0] = Integer.parseInt(s[0]);
for (int i = 1; i < s.length; i++) {
nums[i] = Integer.parseInt(s[i]);
}
// 从前往后找,如果左<右,那就截止到右边即可
// 如果左 > 右,继续往后走,找到后面最高的那个
int len = nums.length;
int left = 0;
int maxArea = 0;
// 记录最大面积时左右坐标
int p = 0, q = 0;
while (left + 1 < len) {
if (nums[left] < nums[left + 1]) {
left++;
continue;
}
int right = left + 1;
int maxIndex = left + 1;
// 找到比left位置高/比其低的里面最高的坐标
while (right < len && nums[left] >= nums[right]) {
maxIndex = nums[right] >= nums[maxIndex] ? right : maxIndex;
right++;
}
// 处理右边比left位置高的坐标
if (right < len && nums[left] <= nums[right]) maxIndex = right;
int area = getArea(nums, left, maxIndex);
if (maxArea < area) {
maxArea = area;
p = left;
q = maxIndex;
}
maxArea = Math.max(maxArea, area);
left = maxIndex;
}
// 处理左右两边界坐标,看能否向内走
int min = Math.min(nums[p], nums[q]);
while (p < len - 1 && min <= nums[p + 1]) p++;
while (q > 0 && min <= nums[q - 1]) q--;
if (maxArea == 0) System.out.println(0);
else System.out.println(p + " " + q + ":" + maxArea);
}
private static int getArea(int[] nums, int left, int right) {
int area = 0;
int height = Math.min(nums[left], nums[right]);
for (int i = left + 1; i < right; i++) {
area += (height - nums[i]);
}
return area;
}
10.狼羊过河
private static void wolfAndSheepRiver() {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();// 羊
int n = sc.nextInt();// 狼
int x = sc.nextInt();// 容量
System.out.println(computeRiver(m, n, x));
}
private static int computeRiver(int m, int n, int x) {
if (m + n <= x) return 1;
// m <= x时,需要考虑
// 1:x=10,m=5,n=15
if (m <= x) {
if (n >= x + m) return 0;
return (m + n - 1) / x + 1;
}
if (n >= m - 1) return 0;
if (n == m - 2) {
if ((x % 2) == 0) return (m + n) / x + 1;
else return (m + n - 3) / (x - 1) + 1;
}
return (m + n - 1) / x + 1;
}
11.递增字符串
private static void minFlipsMonoIncr() {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
int n = s.length();
int dp0 = 0, dp1 = 0;
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
int dp0New = dp0, dp1New = Math.min(dp0, dp1);
if (c == 'B') {
dp0New++;
} else {
dp1New++;
}
dp0 = dp0New;
dp1 = dp1New;
}
System.out.println(Math.min(dp0, dp1));
}
12.最长相似链
class Node {
String str;
int num;//到这个字符的链最长多少
Node(String str) {
this.str = str;
this.num = 0;
}
}
public int longestStrChain(String[] words) {
Map<Integer, List<Node>> map = new HashMap<>();
for (int i = 0; i < words.length; i++) {
List<Node> list = map.getOrDefault(words[i].length(), new LinkedList<>());
Node node = new Node(words[i]);
list.add(node);
map.put(words[i].length(), list);
}
PriorityQueue<Integer> queue = new PriorityQueue<>();
for (Integer key : map.keySet()) {
queue.add(key);
}
int max = 0;
while (!queue.isEmpty()) {
int keyL = queue.poll();
if (queue.isEmpty()) break;
int keyR = queue.peek();
if (keyR != keyL + 1) continue;
List<Node> left = map.get(keyL);
List<Node> right = map.get(keyR);
for (Node st1 : left) {
for (Node st2 : right) {
if (judge(st1.str, st2.str)) {
st2.num = Math.max(st1.num + 1, st2.num);
max = Math.max(st2.num, max);
}
}
}
}
return max + 1;
}
private boolean judge(String st1, String st2) {
boolean flag = false;
int diff = 0;
for (int i = 0; i < st1.length(); i++) {
if (st1.charAt(i) != st2.charAt(i - diff)) {
if (!flag) {
flag = true;
diff = 1;
} else {
return false;
}
}
}
return true;
}
13.相似单词
private static void likeWord() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.nextLine();
// 排序后压缩做key
Map<String, List<String>> map = new HashMap<>();
for (int i = 0; i < n; i++) {
String str = sc.nextLine();
char[] chars = str.toCharArray();
Arrays.sort(chars);
String key = Arrays.toString(chars);
List<String> val = map.getOrDefault(key, new LinkedList<>());
val.add(str);
map.put(key, val);
}
String word = sc.nextLine();
char[] chars = word.toCharArray();
Arrays.sort(chars);
String key = Arrays.toString(chars);
List<String> val = map.get(key);
if (val == null) {
System.out.println("null");
return;
}
Collections.sort(val);
int i = 0;
for (; i < val.size() - 1; i++) {
System.out.print(val.get(i) + " ");
}
System.out.print(val.get(i));
}
14.上班之路
private static void workWay() {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
int c = sc.nextInt();
int n = sc.nextInt();
int m = sc.nextInt();
sc.nextLine();
char[][] graph = new char[n][m];
int startR = 0;
int startC = 0;
int targetR = 0;
int targetC = 0;
for (int i = 0; i < n; i++) {
String str = sc.nextLine();
graph[i] = str.toCharArray();
for (int j = 0; j < m; j++) {
if (graph[i][j] == 'S') {
startR = i;
startC = j;
} else if (graph[i][j] == 'T') {
targetR = i;
targetC = j;
}
}
}
boolean res = findWay(startR, startC, targetR, targetC, graph, t + 1, c, 0);
System.out.println(res ? "YES" : "NO");
}
private static boolean findWay(int startR, int startC, int targetR, int targetC, char[][] graph, int t, int c, int direct) {
if (startR == targetR && startC == targetC) return true;
if (startR < 0 || startC < 0 || startR >= graph.length || startC >= graph[0].length || t < 0) return false;
if (graph[startR][startC] == '*') c--;
if (c < 0) return false;
// 上左下右---1234
return findWay(startR - 1, startC, targetR, targetC, graph, direct == 1 ? t : t - 1, c, 1) ||
findWay(startR, startC - 1, targetR, targetC, graph, direct == 2 ? t : t - 1, c, 2) ||
findWay(startR + 1, startC, targetR, targetC, graph, direct == 3 ? t : t - 1, c, 3) ||
findWay(startR, startC + 1, targetR, targetC, graph, direct == 4 ? t : t - 1, c, 4);
}
15.最少线段覆盖数量
// 每次找当前选择的范围内最远的就对了
private static void minLineCover() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.nextLine();
PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
if (o1[0] != o2[0]) {
return o1[0] - o2[0];
} else {
return o2[1] - o1[1];
}
}
});
for (int i = 0; i < n; i++) {
String s = sc.nextLine();
String[] input = s.split(",");
int[] arr = new int[2];
arr[0] = Integer.valueOf(input[0]);
arr[1] = Integer.valueOf(input[1]);
queue.add(arr);
}
// 开始处理
int res = 1;
int[] poll = queue.poll();
int index = poll[1];
while (!queue.isEmpty()) {
int maxRight = index;
while (!queue.isEmpty() && queue.peek()[0] <= index) {
maxRight = Math.max(queue.poll()[1], maxRight);
}
index = maxRight;
res++;
}
System.out.println(res);
}
16.统计差异值大于相似值二元数组个数
private static void diffBiggerSim() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (compareDiff(arr[i], arr[j])) {
res++;
}
}
}
System.out.println(res);
}
private static boolean compareDiff(int a, int b) {
int flag = 1;
int diff = 0;
int sim = 0;
int max = Math.max(a, b);
while (flag < max) {
diff += ((a & flag) ^ (b & flag));
if ((a & flag) != 0 && (b & flag) != 0) {
sim += flag;
}
flag = flag << 1;
}
return diff > sim;
}
17.删除空格
private static void delBlank() {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
boolean singleFlag = false;
boolean isBlank = false;
char[] chars = str.toCharArray();
StringBuilder sb = new StringBuilder();
int i = 0;
while (i < chars.length) {
StringBuilder temp = new StringBuilder();
while (i < chars.length && check(chars[i])) {
temp.append(chars[i]);
i++;
}
sb.append(temp);
isBlank = false;
while (chars[i] == ' ') {
if (!isBlank) {
sb.append(' ');
isBlank = true;
}
i++;
}
if ((i == chars.length && isBlank) || chars[i] == ',') {
sb.delete(sb.length() - 1, sb.length());
}
singleFlag = false;
if (!check(chars[i])) {
singleFlag = true;
sb.append(chars[i]);
}
temp = new StringBuilder();
while (singleFlag && i < chars.length && !check(chars[i]) && chars[i] != ' ') {
temp.append(chars[i]);
i++;
}
}
System.out.println(sb);
System.out.println(sb.reverse());
}
private static boolean check(char aChar) {
if ((aChar <= 'Z' && aChar >= 'A') || (aChar >= 'a' && aChar <= 'z') || aChar == ',')
return true;
return false;
}
18.求最大数字
private static void comMaxNum() {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
char[] chars = str.toCharArray();
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < chars.length; i++) {
Integer orDefault = map.getOrDefault(chars[i], 0);
map.put(chars[i], orDefault + 1);
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
char cc = chars[i];
if (judgeDel(i, map, chars)) {
map.put(cc, map.get(cc) - 1);
} else {
sb.append(cc);
}
}
System.out.println(sb);
}
// i对应c,到下一个c之间,如果存在比c大的数
// 1:这个数出现次数不大于2,就删了c
// 2:这个数出现次数大于2,递归判断这个数要不要删
// 34533
// 546476644
// 5445795045
static Set<Integer> sets = new HashSet<>();
private static boolean judgeDel(int i, Map<Character, Integer> map, char[] chars) {
if (map.get(chars[i]) <= 2) return false;
if (i == chars.length - 1) return true;
for (int j = i + 1; j < chars.length; j++) {
if (chars[i] < chars[j]) {
return true;
} else if (chars[i] == chars[j]) {
break;
}
}
return false;
}
19.不含101的数
private static void noInclude101() {
Scanner in = new Scanner(System.in);
int l = in.nextInt();
int r = in.nextInt();
int res = r - l + 1;
while (l <= r) {
int temp = 5;
int jud = 7;
while (temp <= l) {
if ((jud & l) == temp) {
res--;
break;
} else {
temp = temp << 1;
jud = jud << 1;
}
}
l++;
}
System.out.println(res);
}
20.取出尽量少的球
private static void getMinBall() {
Scanner sc = new Scanner(System.in);
class Ball {
int index;
int val;
int diff;
Ball(int index, int val) {
this.index = index;
this.val = val;
this.diff = 0;
}
}
int sum = sc.nextInt();
int len = sc.nextInt();
Ball[] arr = new Ball[len];
for (int i = 0; i < len; i++) {
arr[i] = new Ball(i, sc.nextInt());
sum -= arr[i].val;
}
if (sum >= 0) {
System.out.println(" ");
}
// 排序
Arrays.sort(arr, new Comparator<Ball>() {
@Override
public int compare(Ball o1, Ball o2) {
return o1.val - o2.val;
}
});
int index = len - 2;
Ball leftBall = arr[index];
while (sum < 0) {
for (int i = len - 1; i >= index; i--) {
Ball ball = arr[i];
ball.diff = ball.val - leftBall.val;
sum += ball.diff;
}
index--;
leftBall = arr[index];
}
Arrays.sort(arr, new Comparator<Ball>() {
@Override
public int compare(Ball o1, Ball o2) {
return o1.index - o2.index;
}
});
for (int i = 0; i < len; i++) {
System.out.print(" " + arr[i].diff);
}
}
21.对称字符
public static void reverseStr() {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for (int i = 0; i < n; i++) {
int a = sc.nextInt();
long b = sc.nextLong();
System.out.println(findReverseColor(a, b) == 1 ? "RED" : "BLUE");
}
}
/**
* 1 red -1 blue
* n:第几次反转
* k:第几个
*/
private static int findReverseColor(int n, long k) {
if (n == 1) return 1;
if (n == 2) {
return k == 0 ? -1 : 1;
}
int len = (int) Math.pow(2, n - 1);
if (k >= len / 2) {
return findReverseColor(n - 1, k - len / 2);
} else {
return -findReverseColor(n - 1, k);
}
}
22.分奖金
private static void salary() {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = in.nextInt();
}
int[] res = new int[n];
for (int i = 0; i < n; i++) {
res[i] = arr[i];
for (int j = i + 1; j < n; j++) {
if (arr[j] > arr[i]) {
res[i] = (arr[j] - res[i]) * (j - i);
break;
}
}
}
for (int i = 0; i < n - 1; i++) {
System.out.print(res[i] + " ");
}
System.out.print(res[n - 1]);
}
23.查找树中元素
public class huawei {
// 查找树中元素
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int size = Integer.parseInt(in.nextLine());
// 存储树结构
int[][] nodes = new int[size][];
for (int i = 0; i < size; i++) {
nodes[i] = parseOneLine(in.nextLine());
}
// 要找的坐标
int[] xy = parseOneLine(in.nextLine());
// 执行查找
String result = doQuery(nodes, xy[0], xy[1]);
System.out.println(result);
}
private static int[] parseOneLine(String text) {
ByteArrayInputStream stream = new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
Scanner in = new Scanner(stream);
List<Integer> list = new ArrayList<>();
while (in.hasNext()) {
list.add(in.nextInt());
}
return list.stream().mapToInt(it -> it).toArray();
}
private static String doQuery(int[][] nodes, int x, int y) {
if (x < 0 || y < 0) {
return "{}";
}
// Please enter you code to implement this function
// 首先遍历,找到第x层的数据有哪些,然后找出来第y个即可
if(x == 0) return "{" + nodes[0][0] + "}";
x--;
Deque<Integer> deque = new LinkedList<>();
for(int i=1;i<nodes[0].length;i++){
deque.addLast(nodes[0][i]);
}
while(x-- > 0){
int size = deque.size();
for (int i = 0; i < size; i++) {
Integer index = deque.pollFirst();
for (int j = 1; j < nodes[index].length; j++) {
deque.addLast(nodes[index][j]);
}
}
}
while(y-- > 0){
deque.pollFirst();
}
if (deque.isEmpty()) return "{}";
return "{" + nodes[deque.peekFirst()][0] + "}";
}
}
24.相同数字的积木游戏
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int max = -1;
Map<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < n; i++) {
int num = sc.nextInt();
if(!map.containsKey(num)){
map.put(num,i);
}else {
int diff = i - map.get(num);
max = Math.max(max,diff);
}
}
System.out.println(max);
}
}
25.计算至少需要多少个快递主站点
总体时间介于超时和不超时之间,还可以优化
public class Main {
/**
* 4
* 1 1 1 1
* 1 1 1 0
* 1 1 1 0
* 1 0 0 1
*/
static Set<Integer> sets = new HashSet<>();
public static void main(String[] args) {
// 读取数据
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] arr = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
arr[i][j] = sc.nextInt();
}
}
// 这是一个无向图,所以随便选择一个节点开始遍历,被遍历过的节点记录在集合里
int res = 0;
for (int i = 0; i < n; i++) {
if(!sets.contains(i)){
bfs(arr,i);
res++;
}
}
System.out.println(res);
}
private static void bfs(int[][] arr, int i) {
if(sets.contains(i)) return;
sets.add(i);
int[] indexs = arr[i];
int n = arr.length;
for (int j = 0; j < n; j++) {
if(indexs[j] == 1 && !sets.contains(j)){
bfs(arr,j);
}
}
}
}
26.贪心的商人
本题需要支持多次买卖求最大,但是无论是一次买卖还是多次买卖,最后结果都是只通过80%,可能还要考虑是否每次将货物全部买卖,也可能是有20%的用例不准确
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int number = sc.nextInt();
int days = sc.nextInt();
int[] limit = new int[number];
for (int i = 0; i < number; i++) {
limit[i] = sc.nextInt();
}
int[][] goods = new int[number][days];
for (int i = 0; i < number; i++) {
for (int j = 0; j < days; j++) {
goods[i][j] = sc.nextInt();
}
}
int maxMoney = 0;
// 因为几件商品没有关联性,因此可以分别计算每件商品的最大利润
for (int i = 0; i < number; i++) {
// 计算第i件商品利润
//int money = getMoney2(limit[i], goods[i]);
int money = getMoney(limit[i], goods[i]);
maxMoney += money;
}
System.out.println(maxMoney);
}
// 当前是一次买卖,实际上本题不限制买卖次数
private static int getMoney2(int maxVolume, int[] moneyArr) {
// 依次遍历每天金额,在当天,只有两种状态,买入了和没买入
int len = moneyArr.length;
// dp[i][0]表示第i天不持有商品的最大利润
// dp[i][1]表示第i天持有商品的最大利润
int[][] dp = new int[len][2];
dp[0][0] = 0;
dp[0][1] = -moneyArr[0] * maxVolume;
for (int i = 1; i < len; i++) {
dp[i][0] = Math.max(dp[i - 1][1] + moneyArr[i] * maxVolume, dp[i - 1][0]);
dp[i][1] = Math.max(dp[i - 1][0] - moneyArr[i] * maxVolume, dp[i - 1][1]);
}
return Math.max(0, dp[len - 1][0]);
}
// 优化版本,支持多次买卖---依然80通过率
private static int getMoney(int maxVolume, int[] moneyArr) {
int len = moneyArr.length;
//首先是交易次数,最多为 days/2
int maxBuySell = len / 2;
// 统计手上货物哪天买入,
int[][] buy = new int[len][maxBuySell + 1];
// 统计手上货物哪天卖出
int[][] sell = new int[len][maxBuySell + 1];
// 初始化
buy[0][0] = -maxVolume * moneyArr[0];
sell[0][0] = 0;
// 初始化边界条件
for (int i = 1; i <= maxBuySell; i++) {
buy[0][i] = Integer.MIN_VALUE / 2;
sell[0][i] = Integer.MIN_VALUE / 2;
}
for (int i = 1; i < len; i++) {
int price = maxVolume * moneyArr[i];
buy[i][0] = Math.max(buy[i - 1][0], sell[i - 1][0] - price);
for (int j = 1; j <= maxBuySell; j++) {
buy[i][j] = Math.max(buy[i - 1][j], sell[i - 1][j] - price);
sell[i][j] = Math.max(sell[i - 1][j], buy[i - 1][j - 1] + price);
}
}
int res = 0;
for (int i = 0; i <= maxBuySell; i++) {
res = Math.max(sell[len - 1][i], res);
}
return res;
}
}