牛客在线编程题目-华为机试-中等

题号 题目 知识点 难度 通过率
HJ16 购物单 动态规划 中等 21.21%
HJ17 坐标移动 字符串 中等 24.79%
HJ20 密码验证合格程序 数组 字符串 模拟 中等 28.91%
HJ24 合唱队 队列 动态规划 中等 26.04%
HJ26 字符串排序 字符串 排序 中等 36.80%
HJ27 查找兄弟单词 中等 21.10%
HJ29 字符串加解密 字符串 模拟 中等 27.18%
HJ32 密码截取 字符串 动态规划 中等 29.40%
HJ33 整数与IP地址间的转换 字符串 模拟 中等 31.95%
HJ36 字符串加密 字符串 中等 40.82%
HJ38 求小球落地5次后所经历的路程和第5次反弹的高度 模拟 中等 39.23%
HJ41 称砝码 字符串 哈希 中等 40.68%
HJ43 迷宫问题 广度优先搜索(BFS) dfs 中等 35.60%
HJ45 名字的漂亮度 字符串 贪心 中等 39.11%
HJ48 从单向链表中删除指定值的节点 链表 中等 40.08%
HJ50 四则运算 字符串 栈 基础数学 中等 57.25%
HJ52 计算字符串的编辑距离 字符串 动态规划 中等 39.79%
HJ55 挑7 穷举 基础数学 中等 44.49%
HJ57 高精度整数加法 字符串 中等 38.26%
HJ59 找出字符串中第一个只出现一次的字符 字符串 中等 33.40%
HJ63 DNA序列 字符串 中等 42.09%
HJ64 MP3光标位置 数组 中等 30.71%
HJ65 查找两个字符串a,b中的最长公共子串 字符串 中等 36.03%
HJ66 配置文件恢复 字符串 中等 42.47%
HJ67 24点游戏算法 dfs 中等 36.81%
HJ69 矩阵乘法 数组 中等 45.17%
HJ70 矩阵乘法计算量估算 字符串 栈 中等 42.50%
HJ71 字符串通配符 字符串 中等 29.45%
HJ74 参数解析 字符串 模拟 中等 35.33%
HJ75 公共子串计算 字符串 动态规划 中等 40.68%
HJ77 火车进站 中等 46.09%
HJ82 将真分数分解为埃及分数 基础数学 中等 42.94%
HJ90 合法IP 字符串 链表 栈 队列 中等 31.01%
HJ92 在字符串中找出连续最长的数字串 字符串 模拟 中等 31.23%
HJ103 Redraiment的走法 排序 中等 28.84%
HJ107 求解立方根 基础数学 二分 中等 28.44%

1.购物单

public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNextLine()) {int money = sc.nextInt();int m = sc.nextInt();sc.nextLine();money /= 10;int[][] prices = new int[m+1][3];int[][] weights = new int[m+1][3];for(int i=1; i<= m; i++) {int a = sc.nextInt();int b = sc.nextInt();int c = sc.nextInt();a /= 10;    // price ?b = b * a;if (c == 0) {// 主件prices[i][0] = a;weights[i][0] = b;} else if (prices[c][1] == 0) {// 附件1prices[c][1] = a;weights[c][1] = b;} else {// 附件2prices[c][2] = a;weights[c][2] = b; }sc.nextLine();}int[][] dp = new int[m+1][money+1];for(int i=1; i<=m; i++) {for(int j=1; j<=money; j++) {int a = prices[i][0];int b = weights[i][0];int c = prices[i][1];int d = weights[i][1];int e = prices[i][2];int f = weights[i][2];dp[i][j] = j - a >= 0 ? Math.max(dp[i-1][j], dp[i-1][j-a] + b) : dp[i-1][j];dp[i][j] = j-a-c >= 0 ? Math.max(dp[i][j], dp[i-1][j-a-c] + b + d):dp[i][j];dp[i][j] = j-a-e >= 0 ? Math.max(dp[i][j], dp[i-1][j-a-e] + b + f):dp[i][j];dp[i][j] = j-a-c-e >= 0 ? Math.max(dp[i][j], dp[i-1][j-a-c-e] + b +d + f):dp[i][j];}}System.out.println(dp[m][money] * 10);}}
}

2.坐标移动

public class Main{public static void main(String[] args) {Scanner sc = new Scanner(System.in);String[] str = sc.nextLine().split(";");int x = 0, y = 0;for(String s : str) {// 不满足题目给定坐标规则if(!s.matches("[WASD][0-9]{1,2}")){continue;}int val = Integer.valueOf(s.substring(1));switch (s.charAt(0)) {case 'W':y += val;break;case 'S':y -= val;break;case 'A':x -= val;break;case 'D':x += val;break;}}System.out.println(x+","+y);}
}

3.密码验证合格程序

public class Main{public static void main(String[] arg){Scanner sc = new Scanner(System.in);while(sc.hasNext()) {String str = sc.next();if (str.length() <= 8) {System.out.println("NG");continue;}if (getMatch(str)) {System.out.println("NG");continue;}if (hasSubStr(str, 0, 3)) {System.out.println("NG");continue;}System.out.println("OK");}}private static boolean hasSubStr(String str, int l, int r) {if (r >= str.length()) {return false;}if (str.substring(r).contains(str.substring(l, r))) {return true;} else {return hasSubStr(str, l+1, r+1);}}// 检查是否满足正则private static boolean getMatch(String str){int count = 0;Pattern p1 = Pattern.compile("[A-Z]");if(p1.matcher(str).find()){count++;}Pattern p2 = Pattern.compile("[a-z]");if(p2.matcher(str).find()){count++;}Pattern p3 = Pattern.compile("[0-9]");if(p3.matcher(str).find()){count++;}Pattern p4 = Pattern.compile("[^a-zA-Z0-9]");if(p4.matcher(str).find()){count++;}if(count >= 3){return false;}else{return true;}}
}

4.合唱队

public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {int n = sc.nextInt();int[] arr = new int[n];for(int i=0; i<n; i++) {arr[i] = sc.nextInt();}int[] left = new int[n]; //存储每个数左边小于其的数的个数int[] right = new int[n];//存储每个数右边小于其的数的个数left[0] = arr[0];right[n - 1] = arr[n-1];int num[] =new  int [n];//记录以i为终点的从左向右和从右向走的子序列元素个数int index = 1;//记录当前子序列的长度for(int i=1; i<n; i++) {if (arr[i] > left[index - 1]) {//直接放在尾部num[i] = index;left[index++] = arr[i];} else {int low = 0, high = index - 1;while(low < high) {int mid = (low + high) / 2;if (left[mid] < arr[i]) {low = mid+1;} else {high = mid;}}//将所属位置替换为当前元素left[low] = arr[i];//当前位置i的左侧元素个数num[i] = low;}}index = 1;for(int i=n-2; i>=0; i--) {if(arr[i] > right[index - 1]) {num[i] += index;right[index++] = arr[i];} else {int low = 0, high = index - 1;while(low < high) {int mid = (high + low) / 2;if (right[mid] < arr[i]) {low = mid + 1;} else {high = mid;}}right[low] = arr[i];num[i] += low;}}int max = 1;for(int number : num) {max = Math.max(max,number);}System.out.println(n - max);}}
}

5.字符串排序

public class Main {public static String sort(String str) {// 先将英文字母收集起来List<Character> letters = new ArrayList<>();for (char ch : str.toCharArray()) {if (Character.isLetter(ch)) {letters.add(ch);}}// 将英文字母先排序好letters.sort(new Comparator<Character>() {public int compare(Character a, Character b) {return Character.toLowerCase(a) - Character.toLowerCase(b);}});// 若是非英文字母则直接添加StringBuilder sb = new StringBuilder();for(int i=0, j=0; i < str.length(); i++) {if (Character.isLetter(str.charAt(i))) {sb.append(letters.get(j++));} else {sb.append(str.charAt(i));}}return sb.toString();}public static void main(String[] args) {Scanner in = new Scanner(System.in);while (in.hasNextLine()) {String str = in.nextLine();String res = sort(str);System.out.println(res);}}
}

6.查找兄弟单词

public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);while (scanner.hasNext()) {String[] ss = scanner.nextLine().split(" ");Integer a = Integer.parseInt(ss[0]);String x = ss[ss.length - 2];Integer k = Integer.parseInt(ss[ss.length - 1]);List<String> list = new ArrayList<>();for (int i = 1; i <= a ; i++) {if (isBrother(x, ss[i])) {list.add(ss[i]);}}int size = list.size();System.out.println(size);if (size >= k) {Collections.sort(list);System.out.println(list.get(k - 1));}}}public static boolean isBrother(String x, String y) {if (x.length() != y.length() || y.equals(x)) {return false;}char[] s = x.toCharArray();char[] j = y.toCharArray();Arrays.sort(s);Arrays.sort(j);return new String(s).equals(new String(j));}
}

7.字符串加解密

public class Main{public static void main(String[] args){Scanner in = new Scanner(System.in);while(in.hasNext()){System.out.println(encode(in.nextLine()));System.out.println(decode(in.nextLine()));}}//加密函数private static String encode(String code){char[] t = code.toCharArray();    //将String对象转换为字符数组for(int i=0; i < t.length; i++){if(t[i]>='a' && t[i]<'z')t[i] = (char)(t[i] - 'a' + 'A' + 1);else if(t[i] == 'z')t[i] = 'A';else if(t[i]>='A' && t[i]<'Z')t[i] = (char)(t[i] - 'A' + 'a' + 1);else if(t[i] == 'Z')t[i] = 'a';else if(t[i]>='0' && t[i]<'9')t[i] = (char)(t[i]+1);else if(t[i] == '9')t[i] = '0';}return String.valueOf(t);}//解密函数private static String decode(String password){char[] t = password.toCharArray();for(int i=0; i < t.length; i++){if(t[i]>'a' && t[i]<='z')t[i] = (char)(t[i] - 'a' + 'A' - 1);else if(t[i] == 'a')t[i] = 'Z';else if(t[i]>'A' && t[i]<='Z')t[i] = (char)(t[i] - 'A' + 'a' - 1);else if(t[i] == 'A')t[i] = 'z';else if(t[i]>'0' && t[i]<='9')t[i] = (char)(t[i]-1);else if(t[i] == '0')t[i] = '9';}return String.valueOf(t);}
}

8.密码截取

public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String s = sc.nextLine();System.out.println(solution(s));}private static int solution(String s) {int res = 0;for(int i = 0; i < s.length(); i++) {// ABA型int len1 = longest(s, i, i);// ABBA型int len2 = longest(s, i, i + 1);res = Math.max(res, len1 > len2 ? len1 : len2);}return res;}private static int longest(String s, int l, int r) {while(l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) {l--;r++;}return r - l - 1;}
}

9.整数与IP地址间的转换

public class Main {public static String convert(String str) {// ipv4 -> intif (str.contains(".")) {String[] fields = str.split("\\.");long result = 0;for (int i = 0; i < 4; i++) {result = result * 256 + Integer.parseInt(fields[i]);}return "" + result;}// int -> ipv4long ipv4 = Long.parseLong(str);String result = "";for (int i = 0; i < 4; i++) {result = ipv4 % 256 + "." + result;ipv4 /= 256;}return result.substring(0, result.length() - 1);}public static void main(String[] args) {Scanner in = new Scanner(System.in);while (in.hasNext()) {String str = in.next();String res = convert(str);System.out.println(res);}}
}

10.字符串加密

public class Main{public static void main(String args[]) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {String s1 = sc.nextLine().toUpperCase();String s2 = sc.nextLine();char[] chars1 = s1.toCharArray();char[] chars2 = s2.toCharArray();LinkedHashSet<Character> set = new LinkedHashSet();for (int i = 0; i < chars1.length; i++) {set.add(chars1[i]);}int k = 0;while (set.size() < 26) {char a = (char) ('A' + k);set.add(a);k++;}ArrayList<Character> list = new ArrayList<>(set);StringBuffer sb = new StringBuffer();for (int i = 0; i < chars2.length; i++) {if (chars2[i] == ' ') {sb.append(chars2[i]);} else if (chars2[i] < 'a') {int n = (int) (chars2[i] - 'A');char c = list.get(n);sb.append(c);} else {int n = (int) (chars2[i] - 'a');char c = (char)(list.get(n)+'a'-'A');sb.append(c);}}System.out.println(sb.toString());}}
}

11.求小球落地5次后所经历的路程和第5次反弹的高度

public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNextLine()) {double h = Double.parseDouble(sc.nextLine());double tmp = h / 2;for(int i=1; i<5; i++) {h += tmp * 2;tmp /= 2;}System.out.println(h);System.out.println(tmp);}}
}

12.称砝码

public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);while (in.hasNextInt()) { // 注意 while 处理多个 caseHashSet<Integer> set = new HashSet<>();//存放所有可能的结果,不用担心重复问题set.add(0);//初始化为0int n = in.nextInt();//个数int[] w = new int[n];int[] nums = new int[n];for(int i=0;i<n;i++){w[i] = in.nextInt();//砝码的重量}for(int i=0;i<n;i++){nums[i] = in.nextInt();//砝码个数}for(int i=0;i<n;i++){//遍历砝码ArrayList<Integer> list = new ArrayList<>(set);//取当前所有的结果for(int j=1;j<=nums[i];j++){//遍历个数for(int k=0;k<list.size();k++){set.add(list.get(k) + w[i] * j);}}}System.out.println(set.size());}}
}

13.迷宫问题

// 题目已经提示了【迷宫只有一条通道】,则直接使用 DFS 找路径就行了,如果有多条路径找最短考虑使用 BFS
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextInt()) { // 注意 while 处理多个 caseint n = in.nextInt();int m = in.nextInt();// 构造迷宫int[][] map = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {map[i][j] = in.nextInt();}}// 路径存储的数组List<Pos> path = new ArrayList<>();// DFS 搜索路径dfs(map, 0, 0, path);// 输出for (Pos p : path) {System.out.println("(" + p.x + "," + p.y + ")");}}}// 返回值 标记是否找到可通行的路劲public static boolean dfs(int[][] map, int x, int y, List<Pos> path) {// 添加路径并标记已走path.add(new Pos(x, y));map[x][y] = 1;// 结束标志if (x == map.length - 1 && y == map[0].length - 1) {return true;}// 向下能走时if (x + 1 < map.length && map[x + 1][y] == 0) {if (dfs(map, x + 1, y, path)) {return true;}}// 向右能走时if (y + 1 < map[0].length && map[x][y + 1] == 0) {if (dfs(map, x, y + 1, path)) {return true;}}// 向上能走时if (x - 1 > -1 && map[x - 1][y] == 0) {if (dfs(map, x - 1, y, path)) {return true;}}// 向左能走时if (y - 1 > -1 && map[x][y - 1] == 0) {if (dfs(map, x, y - 1, path)) {return true;}}// 回溯path.remove(path.size() - 1);map[x][y] = 0;return false;}// 简单的位置类public static class Pos {int x;int y;public Pos(int x, int y) {this.x = x;this.y = y;}}
}

14.名字的漂亮度

public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);while (in.hasNext()) {int n = in.nextInt();for (int i = 0; i < n; i++) {// 读取到空白符就结束String str = in.next();int s[] = new int[128];for (int j = 0; j < str.length(); j++) {s[str.charAt(j)]++;}Arrays.sort(s);int mul = 26, sum = 0;for (int j = s.length - 1; j >= 0 && s[j] > 0; j--) {sum += s[j] * mul;mul--;}System.out.println(sum);}}}
}

15.从单向链表中删除指定值的节点

public class Main {static class ListNode {int val;ListNode next;static ListNode head;ListNode(int val) {this.val = val;this.next = null;head = this;}ListNode(int val, ListNode next) {this.val = val;this.next = next;}public ListNode getNode(int val) {ListNode p = head;while (p.val != val) {p = p.next;}return p;}public void insert(int data) {this.next = new ListNode(data, this.next);}public void delete(int node) {ListNode dummy = new ListNode(0, head);ListNode p = dummy;while (p.next != null && p.next.val != node) {p = p.next;}if (p.next != null) {p.next = p.next.next;}head = dummy.next;}public void print() {ListNode p = head;while (p != null) {System.out.print(p.val + " ");p = p.next;}System.out.println();}}public static void main(String[] args) {Scanner in = new Scanner(System.in);while (in.hasNext()) {int n = Integer.parseInt(in.next());int val = Integer.parseInt(in.next());ListNode listHead = new ListNode(val);for (int i = 1; i < n; i++) {val = Integer.parseInt(in.next());int existNodeVal = Integer.parseInt(in.next());ListNode p = listHead.getNode(existNodeVal);p.insert(val);}val = Integer.parseInt(in.next());listHead.delete(val);listHead.print();}}
}

16.四则运算

解法1:利用栈

用o1和o2来储存当前符号,具体定义为:

+号时o1=1; -号时o1=-1

*号时o2=1, /号时o2=-1

通过表达式res=num1+o1×num2来保存当前算式,其中num1为已经计算部分的值,而num2是正在计算部分的值,num1和num2中间由±隔开,其中num2正在通过×/计算出结果

当遇到数字时,我们直接获取数字,并且计算o2,获得num2

当遇到±时,代表前面的公式已经计算完毕,计算num1,并更新o1,o2,num2

当遇到×/时,需要对num2进行更新

当遇到左括号时,我们要把现在所有结果入栈,并且重置参数

当遇到右括号时,我们要获得当前数字来更新num2

public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String line = sc.nextLine();int res = calc(line);System.out.println(res);}private static int calc(String line) {int len = line.length();int num1 = 0;int o1 = 1;int num2 = 1;int o2 = 1;Stack<Integer> stk = new Stack<>();for (int i = 0; i < len; i++) {char c = line.charAt(i);if (Character.isDigit(c)) {  //遇到数字则定义num2int cur = 0;while (i < len && Character.isDigit(line.charAt(i))) {cur = cur * 10 + (line.charAt(i) - '0');i++;}i--;num2 = o2 == 1 ? num2 * cur : num2 / cur;} else if (c == '*' || c == '/') {  //遇到×÷定义o2o2 = c == '*' ? 1 : -1;} else if (c == '(' || c == '{' || c == '[') {  //遇到括号则保存当前结果,并初始化stk.push(num1);stk.push(o1);stk.push(num2);stk.push(o2);num1 = 0;o1 = 1;num2 = 1;o2 = 1;} else if (c == '+' || c == '-') {  //遇到加减,说明可以开始计算,计算num1并对定义其他几个变量if (c == '-' && (i == 0 || line.charAt(i - 1) == '(' || line.charAt(i - 1) == '[' || line.charAt(i - 1) == '{')) {o1 = -1;continue;}num1 = num1 + o1 * num2;o1 = (c == '+' ? 1 : -1);num2 = 1;o2 = 1;} else {  //遇到右括号,则出栈,并计算num2int cur = num1 + o1 * num2;o2 = stk.pop();num2 = stk.pop();o1 = stk.pop();num1 = stk.pop();num2 = o2 == 1 ? num2 * cur : num2 / cur;}}return num1 + o1 * num2;}
}
解法2: 逆波兰表达式
public class Main {public static void main(String[] args){Scanner sc = new Scanner(System.in);String line = sc.nextLine();List<String> infix = expressionToList(line);  // ListList<String> suffix = infixToSuffix(infix); // 中缀转后缀Stack<String> stk = new Stack<>();    // 存储中间结果// 逆波兰计算器for (int i = 0; i < suffix.size(); i++) {String curr = suffix.get(i);if (isOper(curr)) {String num2 = stk.pop();String num1 = stk.pop();String reuslt = cal(num1, curr, num2);stk.push(reuslt);} else { // 数字直接入栈stk.push(curr);}}System.out.println(stk.pop());}public static String cal(String num1, String oper, String num2) {Long result = 0l;Long a = Long.parseLong(num1);Long b = Long.parseLong(num2);switch (oper) {case "+":result = a + b;break;case "-":result = a - b;break;case "*":result = a * b;break;case "/":result = a / b;break;}return String.valueOf(result);}public static List<String> infixToSuffix(List<String> infix) {List<String> suffix = new ArrayList<>();Stack<String> stack1 = new Stack<>();   // 只用于保存操作符Stack<String> stack2 = new Stack<>();   // 用于保存中间结果for (int i = 0; i < infix.size(); i++) {String tmp = infix.get(i);if (isOper(tmp)) {   // 操作符要根据情况来入栈 1if (stack1.isEmpty() || "(".equals(tmp) || "[".equals(tmp) || "{".equals(tmp)) {// 如果 stack1 是空的,或者 tmp 是左括号,直接入栈stack1.push(tmp);} else { // stack1 不是空的,且 tmp 不是左括号if (")".equals(tmp) || "]".equals(tmp) || "}".equals(tmp)) {// tmp 是右括号,则把 stack1 遇到左括号之前,全部倒入 stack2while (!("(".equals(stack1.peek()) || "[".equals(stack1.peek()) || "{".equals(stack1.peek()))) {stack2.push(stack1.pop());}stack1.pop();   // 丢掉左括号} else {// tmp 是 +-*/ 其中之一while (!stack1.isEmpty() && priority(stack1.peek()) >= priority(tmp)) {// 在 tmp 能够碾压 stack1 的栈顶操作符之前,把 stack1 的栈顶操作符倒入 stack 2 中stack2.push(stack1.pop());}// 离开 while 时,要么 stack1 已经倒空了,要么就是现在 tmp 可以压住 stack.peek() 了stack1.push(tmp);}}} else { // 操作数直接入栈 2stack2.push(tmp);}}// stack1 剩余操作符全部倒入 stack2while (!stack1.isEmpty()) {stack2.push(stack1.pop());}// stack2 的逆序才是结果,所以要再倒一次while (!stack2.isEmpty()) {stack1.push(stack2.pop());}// 现在 stack1 的元素倒出来的顺序就是后缀表达式while (!stack1.isEmpty()) {suffix.add(stack1.pop());}return suffix;}public static List<String> expressionToList(String expression) {List<String> list = new ArrayList<>();int len = expression.length();String keepNum = "";for (int i = 0; i < len; i++) {char c = expression.charAt(i);if (Character.isDigit(c)) {if (i != len - 1 && Character.isDigit(expression.charAt(i + 1))) {// 如果下一个字符也是数字keepNum += c;} else {// 当前是最后一个字符,或者下一个开始不是数字keepNum += c;list.add(keepNum);keepNum = "";}}else if(c == '-'){if(i==0 || expression.charAt(i-1)=='(' || expression.charAt(i-1)=='[' || expression.charAt(i-1)=='{'){keepNum += c;}else{list.add(c + "");}}else{list.add(c + "");}}return list;}public static boolean isOper(String str) {return "+".equals(str) || "-".equals(str) || "*".equals(str) || "/".equals(str) ||"(".equals(str) || ")".equals(str) || "[".equals(str) || "]".equals(str) ||"{".equals(str) || "}".equals(str);}public static int priority(String oper) {if ("+".equals(oper) || "-".equals(oper)) {return 0;} else if ("*".equals(oper) || "/".equals(oper)) {return 1;} else {return -1;}}
}

17.计算字符串的编辑距离

public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {String str1 = sc.nextLine();String str2 = sc.nextLine();System.out.println(stringDistance(str1.toCharArray(),str2.toCharArray()));}}private static int stringDistance(char[] a, char[] b) {int[][] len = new int[a.length + 1][b.length + 1];for (int i = 0; i < len.length; i++) {len[i][0] = i;}for (int j = 0; j < len[0].length; j++) {len[0][j] = j;}for (int i = 1; i < len.length; i++) {for (int j = 1; j < len[0].length; j++) {if (a[i - 1] == b[j - 1]) {len[i][j] = len[i - 1][j - 1];} else {len[i][j] = Math.min(Math.min(len[i - 1][j], len[i - 1][j - 1]), len[i][j - 1]) + 1;}}}return len[len.length - 1][len[0].length - 1];}
}

18.挑7

public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {int n = sc.nextInt();int sum = 0;for (int i = 1; i <= n; i++) {if (i % 7 == 0) {sum++;} else {String s = String.valueOf(i);if (s.contains("7")) {sum++;}}}System.out.println(sum);}}
}

19.高精度整数加法

解法1:用BigInteger
public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String s1 = scan.next();String s2 = scan.next(); //输入两个数BigInteger a = new BigInteger(s1); //将字符串转成大整数BigInteger b = new BigInteger(s2);System.out.println(a.add(b)); //大整数相加}}
}
解法2:遍历字符相加
public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String s1 = scan.next();String s2 = scan.next(); //输入两个数String res = add(s1, s2); //输出System.out.println(res);}
}private static String add(String s1, String s2) { //两个字符串整数相加StringBuilder res = new StringBuilder();int n = s1.length() - 1;int m = s2.length() - 1;int carry = 0; //进位while (n >= 0 || m >= 0) { //从两个人字符串最后一位开始相加char c1 = n >= 0 ? s1.charAt(n--) : '0'; //没有了就用0代替char c2 = m >= 0 ? s2.charAt(m--) : '0';int sum = (c1 - '0') + (c2 - '0') + carry; //两个数子与进位相加res.append(sum % 10); //余数添加进结果carry = sum / 10;  //进位}if (carry == 1) { //最后的进位res.append(carry);}return res.reverse().toString(); //反转后转成字符串
}

20.找出字符串中第一个只出现一次的字符

public class Main{public static void main(String[] args){Scanner sc = new Scanner(System.in);while(sc.hasNextLine()){//设置信号量boolean flag = false;String str = sc.nextLine();for(int i = 0; i < str.length(); i++){//判断每个字符是否出现第二次,如果存在,设置信号量signal为1;if(str.indexOf(str.charAt(i)) == str.lastIndexOf(str.charAt(i))){System.out.print(str.charAt(i));flag = true;break;}}//判断信号,证明不存在重复字符if(!flag){System.out.println(-1);}System.out.println();}}
}

21.DNA序列

public class Main {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String in = "";while ((in = br.readLine()) != null) {int window = Integer.parseInt(br.readLine());int num = 0;int max = num;int left = 0;for(int i = 1; i <= in.length() - window; i++) {char pre = in.charAt(i - 1);char nex = in.charAt(i + window - 1);if(pre == 'G' || pre == 'C') num--;if(nex == 'G' || nex == 'C') num++;if(num > max) {max = num;left = i;}}System.out.println(in.substring(left, left + window));}}
}

22.MP3光标位置

public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {int n = sc.nextInt();String cmd = sc.next();parseCmd(cmd, n);}}public static void parseCmd(String commands, int n) {// 页面的起始位置int start = 1; // 页面的末位置int end = Math.min(n, 4);// 光标的位置, 三个位置都是从1开始int index = 1;for(int i = 0; i < commands.length(); i++) {// 根据向上移动和向下移动的公式,光标位置的变化if(commands.charAt(i) == 'U') {index = (index-1-1+n) % n + 1;} else if(commands.charAt(i) == 'D') {index = index % n + 1;}// 判断滑动窗口的位置是否需要改变if(index < start) {// 光标在窗口之上start = index;end = start + 3;} else if(index > end){// 光标在窗口之下end = index;start = end - 3;}}// 输出窗口内容for(int i = start; i <= end; i++) {System.out.print(i + " ");}System.out.println();// 打印当前光标System.out.println(index);}
}

23.最长公共子串

 public static String commonStr(String shortStr, String longStr){//计算最长子串String result;if(longStr.contains(shortStr)) {return result = shortStr;}int len = shortStr.length() -1; //从短字符串的 length-1开始遍历for(int i =0; i<shortStr.length(); i++) {if(i+ len <= shortStr.length()) {  //子串末尾不能超出short长度result = shortStr.substring(i, i+len);if(longStr.contains(result))return result;} else {len--;i = -1;}}//所有长度遍历return null;
}

24.配置文件恢复

import java.util.*;
import java.io.*;
public class Main {private static HashMap <String, String> map = new HashMap<>();static {map.put("reset", "reset what");map.put("reset board", "board fault");map.put("board add", "where to add");map.put("board delete", "no board at all");map.put("reboot backplane", "impossible");map.put("backplane abort", "install first");}private static ArrayList <String> list = null;//存放每行命令最终匹配的可能性 结果public static void main(String[] args) throws Exception {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String input = "";while ((input = br.readLine() ) != null) {System.out.println(solve(input));}}//判断 map里的每一条指令 是否匹配inputprivate static String solve(String input) {list = new ArrayList<>();//每行重置 一次 listint count = 0;//遍历 mapfor(String key : map.keySet()) {if (compare(input, key)) {count++;}}//如果有 多个匹配结果  返回 失败if (count > 1 || count == 0) {return "unknown command";} else {return list.get(0);//只有一个结果 返回这个命令的唯一 执行结果}}//对一行命令 进行处理private static boolean compare(String input, String command) {String[] inputArray = input.split(" "); //举例 res boString[] commandAarray = command.split(" ");//举例 reset boardif (inputArray.length != commandAarray.length) {return false; //命令的 输入 参数数量 不一致 这个命令一定不匹配}//比较一位//以 输入的命令 为主   进行遍历  输入逐位匹配成功即成功for (int i = 0; i < inputArray.length; i++) {if (!comparePlus(inputArray[i], commandAarray[i])) {return false;}}list.add(map.get(command));//将成功的  执行结果 加入 listreturn true;}//一行命令里   的一位里的  逐位比较private static boolean comparePlus(String input, String command) {//以 输入的命令 为主   进行遍历  输入逐位匹配成功即成功for (int i = 0; i < input.length(); i++) {if (input.charAt(i) != command.charAt(i)) {return false;}}return true;}
}

25.24点游戏算法

public class Main{static int[] nums = new int[4];static boolean[] visit = new boolean[4];static int flag = 0;public static void main(String[] args){Scanner in = new Scanner(System.in);while(in.hasNext()){String[] a = in.nextLine().split(" ");for(int i = 0; i < 4; i ++)nums[i] = Integer.parseInt(a[i]);dfs(0, 0);   System.out.println( flag == 1 );}}// tmp是前面n个数字运算结果,u表示已经使用了多少个数字static boolean dfs(int u,float target){// 递归终止条件:已经使用了数组四个元素,同时结果为24,满足题意if(target == 24 && u == 4){flag = 1;return true;}for(int i = 0; i < 4; i ++){if(visit[i] == false){visit[i] = true;// 加减乘除当前数字num[i]if( dfs(u + 1, target + nums[i]) ||dfs(u + 1, target - nums[i])  ||dfs(u + 1,target * nums[i]) ||dfs(u + 1, target / nums[i])){return true;}// 相当于回溯visit[i] = false;}}return false;}
}

26.矩阵乘法

public class Main {public static int[][] mul(int[][] mat1, int [][]mat2) {int x = mat1.length, y = mat2.length, z = mat2[0].length;int[][] res = new int[x][z];for (int i = 0; i < x; i++) {for (int j = 0; j < z; j++) {for (int k = 0; k < y; k++) {res[i][j] += mat1[i][k] * mat2[k][j];}}}return res;}public static void main(String[] args) {Scanner in = new Scanner(System.in);while (in.hasNextInt()) {int x = in.nextInt(), y = in.nextInt(), z = in.nextInt();int[][] mat1 = new int[x][y];int[][] mat2 = new int[y][z];for (int i = 0; i < x; i++) {for (int j = 0; j < y; j++) {mat1[i][j] = in.nextInt();}}for (int i = 0; i < y; i++) {for (int j = 0; j < z; j++) {mat2[i][j] = in.nextInt();}}int[][] res = mul(mat1, mat2);for (int i = 0; i < x; i++) {for (int j = 0; j < z; j++) {System.out.print(res[i][j] + " ");}System.out.println();}}}
}

27.矩阵乘法计算量估算

public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);while (in.hasNextInt()) {int n = in.nextInt();int a[][] = new int[n][2];for (int i = 0; i < n; i++) {a[i][0] = in.nextInt();a[i][1] = in.nextInt();}String s = in.next();Stack<Integer> stack = new Stack(); // 存放矩阵行数和列数int sum = 0;for (int i = s.length() - 1, j = n - 1; i >= 0; i--) {if (s.charAt(i) >= 'A' && s.charAt(i) <= 'Z') { // 属于字母则把相应的矩阵列数和行数入栈stack.push(a[j][1]);stack.push(a[j][0]);j--;} else if (s.charAt(i) == '(') {                 // 括号:推出计算int x0 = stack.pop(), y0 = stack.pop();     // 矩阵尺寸x0*y0int x1 = stack.pop(), y1 = stack.pop();     // 矩阵尺寸x1*y1sum += x0 * y0 * y1;  // 两个矩阵的乘法次数为x0*y0*y1或x0*x1*y1(其中y0==x1)stack.push(y1);       // 把相乘后得到的矩阵列数入栈stack.push(x0);       // 把相乘后得到的矩阵行数入栈}}System.out.println(sum);}}
}

28.字符串通配符

public class Main {public static void main(String[] args) throws IOException {BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));String str = "";while ((str = bf.readLine()) != null) {str = str.toLowerCase();String s = bf.readLine().toLowerCase();boolean [][] flag = new boolean[str.length() + 1][s.length() + 1];flag[0][0] = true;if (str.charAt(0) == '*') {flag[1][0] = true;}for (int i = 1; i <= str.length(); i++) {char ch = str.charAt(i - 1);for (int j = 1; j <= s.length(); j++) {char c = s.charAt(j - 1);if (ch == '?') {if (check(c)) {flag[i][j] = flag[i - 1][j - 1];} else {flag[i][j] = false;}} else if (ch == '*') {if (check(c)) {flag[i][j] = flag[i - 1][j - 1] || flag[i][j - 1] || flag[i - 1][j];} else {flag[i][j] = false;}} else if (ch == c) {flag[i][j] = flag[i - 1][j - 1];} else {flag[i][j] = false;}}}System.out.println(flag[str.length()][s.length()]);}}public static boolean check(char ch) {if (ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9') {return true;}return false;}
}

正则表达式解法2:

public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNextLine()) {String regx = sc.nextLine().toLowerCase();String string = sc.nextLine().toLowerCase();//做相应的替换regx = regx.replaceAll("\\*{1,}", "[0-9A-Za-z]*");regx = regx.replaceAll("\\?", "[0-9A-Za-z]{1}");boolean result = string.matches(regx);System.out.println(result);}sc.close();
}

29.参数解析

public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String line = scanner.nextLine();StringBuilder sb = new StringBuilder();List<String> list = new ArrayList();boolean flag = false;for (int i = 0; i < line.length(); i++) {char c = line.charAt(i);if (String.valueOf(c).equals("\"")) {flag = flag ? false : true;continue;}if (String.valueOf(c).equals(" ") && !flag) {list.add(sb.toString());sb = new StringBuilder();} else {sb.append(c);}}list.add(sb.toString());System.out.println(list.size());for (String s : list) {System.out.println(s);}}
}

30.公共子串计算

public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);String ss1 = in.nextLine();String ss2 = in.nextLine();String s1 = ss1.length() < ss2.length() ? ss1 : ss2; // 短的字符串String s2 = ss1.length() < ss2.length() ? ss2 : ss1; // 长的字符串int n = 0;for (int i = 0; i < s1.length(); i++) {      // 头指针从第一位开始递增for (int j = s1.length(); j > i; j--) {  // 尾指针从最后一位开始缩减if (s2.contains(s1.substring(i, j))) { // 第一次发现合集的长度一定是最大的n = j - i > n ? j - i : n;       // 取每一次比较的最大值continue;                        // 已经是最大的,无需再进行后续的操作}}}System.out.println(n);}
}

31.火车进站

public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {int n = sc.nextInt();int[] arr = new int[n];for (int i = 0; i < n; i++) {arr[i] = sc.nextInt();}Set<String> set = new TreeSet<>();solve(arr, 0, "", new ArrayList<>(), set);for (String s : set)System.out.println(s.trim());}sc.close();}private static void solve(int[] arr, int index, String res, List<Integer> list, Set<String> set) {if (index == arr.length) {for (int i = list.size() - 1; i >= 0; i--) {res = res + " " + list.get(i);}set.add(res);return ;}while (true) {List<Integer> tmp = new ArrayList<>(list);tmp.add(arr[index]);solve(arr, index + 1, res, tmp, set);if (list.size() == 0)break;res = res + " " + list.remove(list.size() - 1);}}
}

32.将真分数分解为埃及分数

public class Main {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String str = null;while ((str = br.readLine()) != null) {String[] ss = str.split("/");long a = Integer.parseInt(ss[0]);long b = Integer.parseInt(ss[1]);long t;StringBuilder sb = new StringBuilder();while (a != 0) {t = b / a + (b % a == 0 ? 0 : 1);if (b % t == 0 && a >= t) {a -= b / t;sb.append('1').append('/').append(t).append('+');} else {a = a * t - b;b = b * t;    // 这里可能溢出,所以都用longif (a != 0)sb.append('1').append('/').append(t).append('+');else sb.append('1').append('/').append(t);}if (a == 1) {sb.append('1').append('/').append(b);break;}}System.out.println(sb);}}
}

解法2:

数学家斐波那契提出的一种求解真分数的贪心算法,准确的算法表述应该是这样的:
设某个真分数的分子为a,分母为b;
c=(b/a+1)作为分解式中第一个真分数的分母;
a-b%a作为新的a;
b*c作为新的b;
如果a等于1,则最后一个真分数为1/b,算法结束;
如果a大于1但是a能整除b,则最后一个真分数为1/(b/a),算法结束;
否则重复上面的步骤。

public class Main{public static void main(String[] args){Scanner in = new Scanner(System.in);while(in.hasNext()){String res = "";String[] arr = in.nextLine().split("/");String pre = "";int a = Integer.valueOf(arr[0]);int b = Integer.valueOf(arr[1]);while (true){int c = b/a+1;res += "1/";res += c;a = a - b % a;b = b * c;res += "+";if (a == 1){res += "1/";res += b;break;}else if (a > 1 && b % a == 0){res += "1/";res += b/a;break;}}System.out.println(res);}}
}

递归解法3:

/*** 先将 a/b 转换成 1/x+y/z 的形式* y/z 使用递归继续分解,直到分子为1** b除以a,得商x,得余数y   b=a*x+y* a/b = 1/(x+1) + (a-y)/b(x+1)*/
public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {String[] str = sc.next().split("/");// 分子int a = Integer.parseInt(str[0]);// 分母int b = Integer.parseInt(str[1]);StringBuffer result = new StringBuffer();process(a, b, result);System.out.println(result);}}private static void process(int a, int b, StringBuffer result) {if (result.length() != 0) {result.append("+");}int x = b / a;if (a == 1 || b % a == 0) {result.append("1/").append(x);} else {int y = b % a;result.append("1/").append(x + 1);process(a - y, b * (x + 1), result);}}
}

33.合法IP

public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);while (in.hasNext()) {String str = in.next();String[] nums = str.split("\\.", -1);String result = "YES";if (nums.length == 4) {for (String element : nums) { //遍历每个元素,合不合法if (element.length() == 0 || element.length() > 3) { //每段长度等于0,或者长度大于4,都不合法result = "NO";break;}for (Character ch : element.toCharArray()) { //每段的字符必须是数字if (!Character.isDigit(ch)) {result = "NO";break;}}if (element.charAt(0) == '0' && element.length() != 1) { //除0以外,所有0开头的字符串都是非法的result = "NO";break;}if (Integer.parseInt(element) > 255) { //每段对应的数大于255,也是非法的result = "NO";break;}}} else {result = "NO";}System.out.println(result);}}
}

34.在字符串中找出连续最长的数字串

public class Main{public static void main(String[] args) throws Exception{Scanner sc = new Scanner(System.in);while(sc.hasNextLine()){String line = sc.nextLine();String[] ss = line.split("[^0-9]+");int max  = 0;ArrayList<String> list = new ArrayList<>();for(String s : ss){if(s.length() > max){max = s.length();list.clear();list.add(s);}else if(s.length() == max){max = s.length();list.add(s);}}StringBuilder sb = new StringBuilder();for(String item : list){sb.append(item);}sb.append(",").append(max);System.out.println(sb.toString());}}
}

35.Redraiment的走法

public class Main{public static void main(String[] arg) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {scan.nextLine();String[] input1 = scan.nextLine().split(" ");int[] intArr = Arrays.stream(input1).mapToInt(Integer::parseInt).toArray();int[] k=new int[intArr.length];for(int j=1;j<intArr.length;j++){for(int i=0;i<j;i++){if(intArr[i]<intArr[j]){k[j]=Math.max(k[j],k[i]+1);}}}Arrays.sort(k);System.out.println(k[k.length-1]+1);}}
}

解法2:动态规划+二分

public class Main {public static void main(String[] args) throws IOException {BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));String str;while ((str = bf.readLine()) != null) {int len = Integer.parseInt(str);int[] nums = new int[len];String[] split = bf.readLine().split(" ");for (int i = 0; i < len; ++i) {nums[i] = Integer.parseInt(split[i]);}System.out.println(LIS(nums));}}public static int LIS (int[] arr) {int n = arr.length;// 列表的最大子序列 下标从1开始int[] end = new int[n + 1];// 存储每个元素的最大子序列个数int[] dp = new int[n];int len = 1;//子序列的第一个元素默认为数组第一个元素end[1] = arr[0];//第一个元素的最大子序列个数肯定是1dp[0] = 1;for (int i = 1; i < n; i++) {if (end[len] < arr[i]) {//当arr[i] > end[len] 时 arr[i]添加到 end后面end[++len] = arr[i];dp[i] = len;} else {// 当前元素小于end中的最后一个元素 利用二分法寻找第一个大于arr[i]的元素// end[l] 替换为当前元素 dp[]int l = 0;int r = len;while (l <= r) {int mid = (l + r) >> 1;if (end[mid] >= arr[i]) {r = mid - 1;} else {l = mid + 1;}}end[l] = arr[i];dp[i] = l;}}int[]  res = new int[len];for (int i = n - 1; i >= 0; i--) {if (dp[i] == len) {res[--len] = arr[i];}}return res.length;}
}

36.求解立方根

牛顿迭代法:

public class Main {public static void main(String[] args) {Scanner input = new Scanner(System.in);while (input.hasNextDouble()) {double num = input.nextDouble();double x = 1.0;for ( ; Math.abs(Math.pow(x, 3) - num) > 1e-3 ;x = x - ((Math.pow(x, 3) - num) / (3 * Math.pow(x, 2))) );System.out.println(String.format("%.1f", x));}}
}

牛客在线编程-华为机试-中等相关推荐

  1. (python)牛客网(华为机试四)——较难

    本博客为博主解题的部分记录,由于均为自己写的,所以答案并非最优解,有很多地方可以优化. 其他题解合集: (python)牛客网(华为机试一)--入门 (python)牛客网(华为机试二)--简单 (p ...

  2. 牛客网 - 在线编程 - 华为机试 - 求最小公倍数

    题目描述 正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数. 输入描述: 输入两个正整数A和B. 输出描述: 输出A和B的最小公倍数. 示例 ...

  3. (Python) 牛客 在线编程 python入门

    文章目录 前言 AC代码 01 输入输出 NP1 Hello World! NP2 多行输出 NP3 读入字符串 NP4 读入整数数字 NP5 格式化输出(一) NP6 牛牛的小数输出 02 类型转换 ...

  4. 【牛客网】华为机试题(00、C++版本)

    华为机试题,本来以为对一些基础的程序还是有点信心的:不过不练不知道,一练吓一跳.平时虽然也都码程序,但是一到机试题就各种乱七八的不适应.还是要加强一下练习. 1.字符串最后一个单词的长度 题目描述:计 ...

  5. HJ6 质数因子_牛客网_华为机试题

    描述 功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 ) 数据范围: 输入描述: 输入一个整数 输出描述: 按照从小到大的顺序输出它 ...

  6. 牛客在线编程101-93 盛水最多的容器

    描述 给定一个数组height,长度为n,每个数代表坐标轴中的一个点的高度,height[i]是在第i点的高度,请问,从中选2个高度与x轴组成的容器最多能容纳多少水 1.你不能倾斜容器 2.当n小于2 ...

  7. 牛客网计算机考研机试真题-abc

    public class Main{public static void main(String[] args){int c;for(int a=1;a<=4;a++){for(int b=1; ...

  8. java 输入输出总结(牛客、笔试、机试)

    因为踩过坑,所以特别整理了一下,发现其实不少小伙伴同样都是这样,特别简单小结一下,java网上笔试的时候OJ的一些要求的实例 1 单行输入 // 本题为考试单行多行输入输出规范示例,无需提交,不计分. ...

  9. 华为机试中等难度题目

    进制转换 import java.util.Scanner;public class Main{public static void main(String[] args){Scanner sc = ...

最新文章

  1. linux 中如何将文件粘贴到usr下的lib内,学会在Linux下GCC生成和使用静态库和动态库...
  2. C++用FindFirstFile、FindNext递归遍历硬盘的文件
  3. PHP无刷新上传面向过程写法iframe
  4. java web编写计算器_javaWeb 使用 jsp 和 javaBean 实现计算器功能
  5. 【软件开发底层知识修炼】十 链接器-main函数不是第一个被执行的函数
  6. elementUI使用
  7. c# dynamic动态类型和匿名类
  8. ICON素材|装饰图标设计的技巧
  9. SSRF(服务端请求伪造)原理/防御
  10. Cmder的安装与配置
  11. 阿里云企业邮箱用smtp发送邮件失败解决
  12. 那些陪伴了我大学青春的网易博客也要停运啦
  13. 直击AWE2018:当AI遇见LED,诸葛小明给光更多可能
  14. 虚拟机创作ubuntu18的ISO镜像
  15. 钙钛矿型复合氧化物高熵陶瓷/过渡金属碳氮化物高熵陶瓷/固体氧化物燃料电池(SOFC)材料
  16. Python攻关之模块(1)
  17. Abbkine IPKine GFP标签蛋白免疫沉淀试剂盒(磁珠法)
  18. H5小游戏 - 答题游戏
  19. c语言计算年龄的编程,C语言编程实现---计算实际年龄
  20. 2021考生如何做考博英语复习规划?

热门文章

  1. 八道C语言指针笔试题——拿捏指针
  2. bootstrap搭建后台管理页面
  3. python3编写http代理服务器_HTTP代理服务器[Python]
  4. 浅谈语音信号处理系列之二 语音信号处理的基础
  5. xtrabackup安装、进行全量备份增量备份
  6. 精益生产25个必备工具!
  7. 流畅的Python学习
  8. c#获取当前时间 毫秒_C# 当前系统时间获取及时间格式详解
  9. c语言输出字母A的ascii值,ascii是什么意思_C语言中如何输出ASCII码
  10. 别玩手机了,你没时间了!