华为8.12笔试
总体来说不难,小弟AC了1,3题。第二题只过了90%,求大神指点
第一题:买咖啡。一杯咖啡5元,客人会付5,10,20三种面额,一次只买一杯咖啡,初始金额为0,问能否找零。
简单的模拟,注意非法输入的情况。
第二题:给定由0和1构成的二维数组,1可以走,0不能走。限制步长为固定值,问能否从左上角走到右下角public class Q1 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { String[] a = sc.next().split(","); int five = 0; int ten = 0; int i = 1; boolean res = true; while (i <= a.length){ if (a[i - 1].equals("5")) { five++; } else if (a[i - 1].equals("10")) { five--; ten++; } else if (a[i - 1].equals("20")) { if (ten >= 1 && five >= 1) { five--; ten--; } else { five -= 3; } } else { res = false; break; } if (five < 0 || ten < 0) { res = false; break; } else { i++; } } if (i > a.length) i--; System.out.println(res + "," + i); } } }
DFS很轻松就能解决,不知道为什么只过了90%,提示数组越界。检查了好久都不知道哪里出错😂求大神指点
public class Q2 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { long n = sc.nextLong(); if (n == 0) { System.out.println(0); continue; } int row = sc.nextInt(); int col = sc.nextInt(); if (row == 0 || col == 0) { System.out.println(1); continue; } boolean[][] a = new boolean[row][col]; for (int i = 0; i < a.length; i++) { for (int j = 0; j < a[0].length; j++) { a[i][j] = sc.nextInt() == 1; } } if (n >= row && n >= col) { System.out.println(0); continue; } int b = (int)n; boolean[][] visited = new boolean[row][col]; if (dfs(a, 0, 0, visited, b)) { System.out.println(1); } else { System.out.println(0); } } } private static boolean dfs(boolean[][] a, int i, int j, boolean[][] visited, int n) { if (i == a.length - 1 && j == a[0].length - 1) { return true; } if (i < 0 || i >= a.length || j < 0 || j >= a[0].length) { return false; } if (canVisit(a, i - n, j, visited)) { visited[i - n][j] = true; if (dfs(a, i - n, j, visited, n)) { return true; } } if (canVisit(a, i + n, j, visited)) { visited[i + n][j] = true; if (dfs(a, i + n, j, visited, n)) { return true; } } if (canVisit(a, i, j - n, visited)) { visited[i][j - n] = true; if (dfs(a, i, j - n, visited, n)) { return true; } } if (canVisit(a, i, j + n, visited)) { visited[i][j + n] = true; if (dfs(a, i, j + n, visited, n)) { return true; } } return false; } private static boolean canVisit(boolean[][] a, int i, int j, boolean[][] visited) { return i >= 0 && i < a.length && j >= 0 && j < a[0].length && a[i][j] && !visited[i][j]; } }
思路也是模拟:首先生成字符串数组。形状X的长度如果为n,那么X的每一行也有n个字符(加上空字符)。使用两个指针,L最开始指向0,R最开始指向n-1。
对于每一行,先填充L再填充R,别的字符串都为空。换到下一行时L++,R--。如果L == R(n为奇数)或者L + 1 == R,那么换到下一行时应该变为L--,R++。
等L == 0时,再翻转指针L和R的运动方向,变为L++,R--,直到用完所有字符为止。最后再从左到右按列读取,就能得到结果。
public class Q3 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { String[] strs = sc.next().split(","); String s = strs[0]; int n = Integer.parseInt(strs[1]); List<Character[]> list = new ArrayList<>(); int i = 0; boolean close = true; Character[] cur; int l = 0; int r = n - 1; while (i < s.length()) { cur = new Character[n]; if (l == r) {// 边界条件 cur[l] = s.charAt(i++); close = !close; list.add(cur); l--; r++; } else if (l + 1 == r) {// 边界条件 cur[l] = s.charAt(i++); if (i < s.length()) cur[r] = s.charAt(i++); close = !close; list.add(cur); l--; r++; } else if (l == 0 && !close) {// 边界条件 cur[l] = s.charAt(i++); if (i < s.length()) cur[r] = s.charAt(i++); close = !close; list.add(cur); l++; r--; } else {// 通常情况 cur[l] = s.charAt(i++); if (i < s.length()) cur[r] = s.charAt(i++); list.add(cur); if (close) { l++; r--; } else { l--; r++; } } } StringBuilder sb = new StringBuilder(); for (int j = 0; j < n; j++) { for (Character[] c : list) { if (c[j] != null) sb.append(c[j]); } } System.out.println(sb); } } }