牛客在线编程-华为机试-中等
牛客在线编程题目-华为机试-中等
题号 | 题目 | 知识点 | 难度 | 通过率 | |
---|---|---|---|---|---|
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));}}
}
牛客在线编程-华为机试-中等相关推荐
- (python)牛客网(华为机试四)——较难
本博客为博主解题的部分记录,由于均为自己写的,所以答案并非最优解,有很多地方可以优化. 其他题解合集: (python)牛客网(华为机试一)--入门 (python)牛客网(华为机试二)--简单 (p ...
- 牛客网 - 在线编程 - 华为机试 - 求最小公倍数
题目描述 正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数. 输入描述: 输入两个正整数A和B. 输出描述: 输出A和B的最小公倍数. 示例 ...
- (Python) 牛客 在线编程 python入门
文章目录 前言 AC代码 01 输入输出 NP1 Hello World! NP2 多行输出 NP3 读入字符串 NP4 读入整数数字 NP5 格式化输出(一) NP6 牛牛的小数输出 02 类型转换 ...
- 【牛客网】华为机试题(00、C++版本)
华为机试题,本来以为对一些基础的程序还是有点信心的:不过不练不知道,一练吓一跳.平时虽然也都码程序,但是一到机试题就各种乱七八的不适应.还是要加强一下练习. 1.字符串最后一个单词的长度 题目描述:计 ...
- HJ6 质数因子_牛客网_华为机试题
描述 功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 ) 数据范围: 输入描述: 输入一个整数 输出描述: 按照从小到大的顺序输出它 ...
- 牛客在线编程101-93 盛水最多的容器
描述 给定一个数组height,长度为n,每个数代表坐标轴中的一个点的高度,height[i]是在第i点的高度,请问,从中选2个高度与x轴组成的容器最多能容纳多少水 1.你不能倾斜容器 2.当n小于2 ...
- 牛客网计算机考研机试真题-abc
public class Main{public static void main(String[] args){int c;for(int a=1;a<=4;a++){for(int b=1; ...
- java 输入输出总结(牛客、笔试、机试)
因为踩过坑,所以特别整理了一下,发现其实不少小伙伴同样都是这样,特别简单小结一下,java网上笔试的时候OJ的一些要求的实例 1 单行输入 // 本题为考试单行多行输入输出规范示例,无需提交,不计分. ...
- 华为机试中等难度题目
进制转换 import java.util.Scanner;public class Main{public static void main(String[] args){Scanner sc = ...
最新文章
- linux 中如何将文件粘贴到usr下的lib内,学会在Linux下GCC生成和使用静态库和动态库...
- C++用FindFirstFile、FindNext递归遍历硬盘的文件
- PHP无刷新上传面向过程写法iframe
- java web编写计算器_javaWeb 使用 jsp 和 javaBean 实现计算器功能
- 【软件开发底层知识修炼】十 链接器-main函数不是第一个被执行的函数
- elementUI使用
- c# dynamic动态类型和匿名类
- ICON素材|装饰图标设计的技巧
- SSRF(服务端请求伪造)原理/防御
- Cmder的安装与配置
- 阿里云企业邮箱用smtp发送邮件失败解决
- 那些陪伴了我大学青春的网易博客也要停运啦
- 直击AWE2018:当AI遇见LED,诸葛小明给光更多可能
- 虚拟机创作ubuntu18的ISO镜像
- 钙钛矿型复合氧化物高熵陶瓷/过渡金属碳氮化物高熵陶瓷/固体氧化物燃料电池(SOFC)材料
- Python攻关之模块(1)
- Abbkine IPKine GFP标签蛋白免疫沉淀试剂盒(磁珠法)
- H5小游戏 - 答题游戏
- c语言计算年龄的编程,C语言编程实现---计算实际年龄
- 2021考生如何做考博英语复习规划?