- 题目链接
- HJ1 字符串最后一个单词的长度
- HJ2 计算某字符出现次数
- HJ3 明明的随机数
- HJ4 固定长度分割字符串
- HJ5 进制转换
- HJ6 质数因子
- HJ8 合并表记录
- HJ9 整数逆序不含重复数字
- HJ10 统计字符种类
- HJ11 数字颠倒
- HJ12 字符串反转
- HJ13 句子逆序
- HJ14 字符串排序
- HJ15 求二进制中1的个数
- HJ16 购物单
- HJ17 坐标移动
- HJ19 简单错误记录
- HJ20 密码验证合格程序
- HJ21 简单密码
- HJ22 汽水瓶问题
- HJ23 删除字符串中出现次数最少的字符
- HJ26 字符串排序
- HJ28 素数伴侣
- HJ29 字符串加解密
- HJ31 单词倒排
- HJ33 整数与IP地址间的转换
- HJ34 图片整理
- HJ35 三角矩阵
- HJ36 字符串加密
- HJ37 数兔子
- HJ38 小球落地反弹总路程
- HJ40 统计四种字符个数
- HJ41 砝码可称量的重量
- HJ43 迷宫问题
- HJ52 编辑距离
- HJ53 杨辉三角的变形
- HJ54 表达式求值
- HJ55 挑7
- HJ56 完全数计算
- HJ60 查找组成一个偶数最接近的两个素数
- HJ62 二进制中1的个数
- HJ63 DNA序列
- HJ65 最长公共子串
- HJ67 24点
- HJ72 百钱买百鸡问题
- HJ76 尼科彻斯定理
- HJ77 火车进站
- HJ84 统计大写字母个数
- HJ86 二进制中最长连续1
- HJ92 连续最长的数字串
- HJ96 数字首尾加符号
题目链接
刷题链接:https://www.nowcoder.com/exam/oj/ta?tpId=37
参考博客:http://www.amoscloud.com/?cat=56
HJ1 字符串最后一个单词的长度
方法1:用Java的Scanner 类的特性
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);String word = "";while (scan.hasNext()) {word = scan.next();}System.out.println(word.length());}}
HJ2 计算某字符出现次数
描述
写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中该字符的出现次数。(不区分大小写字母)
数据范围: [1,1000]
输入描述:
第一行输入一个由字母和数字以及空格组成的字符串,第二行输入一个字符。
输出描述:
输出字符串中含有该字符的个数。(不区分大小写字母)
代码:
import java.util.*;public class Main{public static void main(String[] args) {Scanner scan = new Scanner(System.in);while(scan.hasNext()) {char[] arr = scan.nextLine().toLowerCase().toCharArray();String str = scan.nextLine().toLowerCase();int count = 0;for(int i = 0; i < arr.length; i++){if(arr[i] == str.charAt(0)){count++;}}System.out.println(count);}}}
HJ3 明明的随机数
描述
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 N 个 1 到 1000 之间的随机整数( N≤1000 ),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作(同一个测试用例里可能会有多组数据(用于不同的调查),希望大家能正确处理)。
注:测试用例保证输入参数的正确性,答题者无需验证。测试用例不止一组。
当没有新的输入时,说明输入结束。
数据范围:n在[1, 1000] ,输入的数字大小满足 [1, 500]
输入描述:
注意:输入可能有多组数据(用于不同的调查)。每组数据都包括多行,第一行先输入随机整数的个数 N ,接下来的 N 行再输入相应个数的整数。具体格式请看下面的”示例”。
输出描述:
返回多行,处理后的结果
方法1:桶排序。
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int n = scan.nextInt();boolean[] map = new boolean[501];for (int i = 0; i < n; i++) {int num = scan.nextInt();map[num] = true;}for (int i = 1; i < 501; i++) {if (map[i]) {System.out.println(i);}}}}}
HJ4 固定长度分割字符串
描述
•连续输入字符串,请按长度为8拆分每个输入字符串并进行输出;
•长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。
(注:本题有多组输入)
输入描述:
连续输入字符串(输入多次,每个字符串长度小于等于100)
输出描述:
依次输出所有分割后的长度为8的新字符串
方法1:补全法。
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.nextLine();// 1. 长度不是8的整数倍,统一补足8个0if (str.length() % 8 != 0) {str = str + "00000000";}// 2. 固定长度截取,并打印while (str.length() >= 8) {System.out.println(str.substring(0, 8));str = str.substring(8);}}}}
HJ5 进制转换
描述:写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。
数据范围:保证结果在int范围内
注意本题有多组输入
输入描述:
输入一个十六进制的数值字符串。注意:一个用例会同时有多组输入数据,请参考帖子https://www.nowcoder.com/discuss/276 处理多组输入的问题。
输出描述:
输出该数值的十进制字符串。不同组的测试用例用\n隔开。
方法1:手动转换
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String hex = scan.nextLine().substring(2);int num = 0;int len = hex.length();for (int i = len - 1; i >= 0; i--) {int temp = hexToNum(hex.charAt(i));num += temp * Math.pow(16, len - 1 - i);}System.out.println(num);}}private static int hexToNum(char c) {switch (c) {case 'A':return 10;case 'B':return 11;case 'C':return 12;case 'D':return 13;case 'E':return 14;case 'F':return 15;default:return Integer.parseInt(String.valueOf(c));}}}
方法2:使用API
import java.util.*;public class Main {// 方法2:使用Java的APIpublic static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.nextLine();int num = Integer.parseInt(str.substring(2), 16);System.out.println(num);}}}
HJ6 质数因子
描述:
输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )
输入描述:
输入一个整数
输出描述:
按照从小到大的顺序输出它的所有质数的因子,以空格隔开。最后一个数后面也要有空格。
方法1:循环相除法。
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int num = scan.nextInt();StringBuilder sb = new StringBuilder();for (int i = 2; i <= Math.sqrt(num); i++) {while (num % i == 0) {sb.append(i);sb.append(" ");num = num / i;}}// num 最后有两种可能:1或某个质数if (num != 1) {sb.append(num);sb.append(" ");}System.out.println(sb);}}}
HJ8 合并表记录
描述
数据表记录包含表索引index和数值value(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照index值升序进行输出。
方法1:Jdk8的流式编程
import java.util.*;import java.util.stream.Collectors;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNext()) {int num = sc.nextInt();Map<Integer, Integer> map = new HashMap<>();for (int i = 0; i < num; i++) {int key=sc.nextInt();int value=sc.nextInt();// 有key 就相加,没有key 就putmap.put(key, map.getOrDefault(key, 0) + value);}// 这一句用到好多jdk8的新语法啊List<Map.Entry<Integer, Integer>> collect = map.entrySet().stream().sorted(((o1, o2) -> {return o1.getKey() - o2.getKey();})).collect(Collectors.toList());for (Map.Entry<Integer, Integer> entry :collect) {System.out.println(entry.getKey() + " " + entry.getValue() );}}}}
方法2:哈希表和有序表
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);HashMap<Integer, Integer> map = new HashMap<>();int num = scan.nextInt();while (scan.hasNext()) {for (int i = 0; i < num; i++) {int key = scan.nextInt();int value = scan.nextInt();if (!map.containsKey(key)) {map.put(key, value);} else {map.put(key, map.get(key) + value);}}// 把map的keySet 排序TreeSet<Integer> treeSet = new TreeSet<>(map.keySet());for (Integer key : treeSet) {System.out.println(key + " " + map.get(key));}}}}
HJ9 整数逆序不含重复数字
描述
输入一个 int 型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。
保证输入的整数最后一位不是 0 。
输入描述:
输入一个int型整数
输出描述:
按照从右向左的阅读顺序,返回一个不含重复数字的新的整数
示例1
输入:9876673
输出:37689
方法1:求余加哈希表。
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while(scan.hasNext()){int num = scan.nextInt();boolean[] arr = new boolean[10];StringBuilder sb = new StringBuilder();// 数组相当于一个哈希表,用来判断某个数字是否出现过while(num != 0){int remainder = num % 10;if(arr[remainder] == false){sb.append(remainder);arr[remainder] = true;}num = num / 10;}System.out.println(sb);}}}
HJ10 统计字符种类
描述:编写一个函数,计算字符串中含有的不同字符的个数。字符在 ASCII 码范围内( 0~127 ,包括 0 和 127 ),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次。
例如,对于字符串 abaca 而言,有 a、b、c 三种不同的字符,因此输出 3 。
输入描述:输入一行没有空格的字符串。
输出描述:输出字符串中范围在(0~127,包括0和127)字符的种数。
示例1
输入:abcb
输出:3
方法1:桶排序
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.nextLine();int count = getCount(str);System.out.println(count);}}// 桶排序public static int getCount(String str) {int count = 0;boolean[] flag = new boolean[128];for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);if (!flag[c]) {flag[c] = true;count++;}}return count;}}
HJ11 数字颠倒
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);String str = scan.nextLine();StringBuilder sb = new StringBuilder(str);sb.reverse();System.out.println(sb);}}
HJ12 字符串反转
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.nextLine();// 将字符串变成char数组再倒序输出char[] chars = str.toCharArray();for (int i = chars.length - 1; i >= 0; i--) {System.out.print(chars[i]);}System.out.println();}}}
HJ13 句子逆序
描述:将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I”
所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符
数据范围:输入的字符串长度满足 【1,1000】
注意本题有多组输入
输入描述:输入一个英文语句,每个单词用空格隔开。保证输入只包含空格和字母。
输出描述:得到逆序的句子
示例1
输入:I am a boy
输出:boy a am I
方法1:字符串用空格分隔
import java.util.*;public class Main{// 方法2:分割逆序拼接public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.nextLine();String[] arr = str.split(" ");StringBuilder sb = new StringBuilder();for (int i = arr.length - 1; i >= 0; i--) {sb.append(arr[i]).append(" ");}System.out.println(sb);}}}
方法2:两次逆序。
import java.util.*;public class Main {// 方法1:两次反转public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.nextLine();char[] arr = str.toCharArray();int len = arr.length;int start = 0;for (int i = 0; i <= len; i++) {// 第一次反转,对单词进行反转if (i == len || arr[i] == ' ') {reverse(arr, start, i - 1);start = i + 1;}}// 第二次反转,对整个字符串进行反转reverse(arr, 0, len - 1);System.out.println(new String(arr));}}// 对数组[start, end]这段区间进行反转public static void reverse(char[] arr, int start, int end) {while (start < end) {char temp = arr[start];arr[start] = arr[end];arr[end] = temp;start++;end--;}}}
HJ14 字符串排序
描述
给定 n 个字符串,请对 n 个字符串按照字典序排列。
数据范围: ,字符串长度满足
输入描述:
输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。
输出描述:
数据输出n行,输出结果为按照字典序排列的字符串。
方法1:手写快速排序,定义比较规则
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);String count = scan.nextLine();int len = Integer.parseInt(count);String[] arr = new String[len];for (int i = 0; i < len; i++) {arr[i] = scan.nextLine();}quickSort(arr, 0, arr.length - 1);for (String str : arr) {System.out.println(str);}}private static void quickSort(String[] arr, int low, int high) {if (low < high) {int pos = partition(arr, low, high);quickSort(arr, low, pos - 1);quickSort(arr, pos + 1, high);}}private static int partition(String[] arr, int low, int high) {String pivot = arr[low];int lt = low;int gt = high;for (int i = low + 1; i <= gt; i++) {int compare = compareTo(arr[i], pivot);if (compare < 0) {swap(arr, i, lt);lt++;} else {swap(arr, i, gt);gt--;i--;}}return lt;}// 定义两个字符串的排序规则private static int compareTo(String a, String b) {int i = 0;char[] arr1 = a.toCharArray();char[] arr2 = b.toCharArray();// 逐个比较while (i < arr1.length && i < arr2.length) {if (arr1[i] == arr2[i]) {i++;} else if (arr1[i] < arr2[i]) {return -1;} else {return 1;}}// 长度一样,说明两个字符串一样if (arr1.length == arr2.length) {return 0;}// a短,返回-1;b短,返回1if (i == arr1.length) {return -1;} else {return 1;}}private static void swap(String[] arr, int i, int j) {String temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}
方法2:使用API
import java.util.*;public class Main {// 方法2:使用APIpublic static void main(String[] args) {Scanner scan = new Scanner(System.in);String count = scan.nextLine();int len = Integer.parseInt(count);String[] arr = new String[len];for (int i = 0; i < len; i++) {arr[i] = scan.nextLine();}Arrays.sort(arr);for (String str : arr) {System.out.println(str);}}}
HJ15 求二进制中1的个数
描述:输入一个 int 型的正整数,计算出该 int 型数据在内存中存储时 1 的个数。
输入描述:输入一个整数(int类型)
输出描述:这个数转换成2进制后,输出1的个数
示例1
输入:5
输出:2
方法1:减一消除法。
用&运算会很巧妙,num & (num - 1),会把num二进制表示中最右侧的1 给消除掉, 每次消除一次就记录次数,直到num变成0,就会得到有多少个1.
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int num = scan.nextInt();int count = 0;while (num != 0) {count++;num = num & (num - 1);}System.out.println(count);}}}
HJ16 购物单
HJ17 坐标移动
方法1:正则加哈希
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);Map<Character, Integer> map = new HashMap<>();while (scan.hasNext()) {String str = scan.nextLine();String[] arr = str.split(";");String regex = "[ADWS]\\d{1}\\d?";int x = 0;int y = 0;for (int i = 0; i < arr.length; i++) {if (arr[i].matches(regex)) {map.put(arr[i].charAt(0), map.getOrDefault(arr[i].charAt(0), 0) + Integer.parseInt(arr[i].substring(1)));}}x = x - map.get('A') + map.get('D');y = y - map.get('S') + map.get('W');System.out.println(x + "," + y);map.clear();}scan.close();}}
方法2:正则表达式
import java.util.*;public class Main {// 方法2:正则表达式public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.nextLine();String[] arr = str.split(";");String regex = "[WASD][0-9]{1,2}";int x = 0;int y = 0;for (int i = 0; i < arr.length; i++) {// 1. 正则表达式匹配合法的字符串if (!arr[i].matches(regex)) {continue;}// 2. 截取字符串中后面的数值部分,int digit = Integer.parseInt(arr[i].substring(1));// 3. 根据移动方向,改变坐标值switch (arr[i].charAt(0)) {case 'W':y += digit;break;case 'S':y -= digit;break;case 'A':x -= digit;break;case 'D':x += digit;break;}}System.out.println(x + "," + y);}}}
HJ19 简单错误记录
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);Map<String, Integer> map = new LinkedHashMap<>();String tstr = null;while (scan.hasNext()) {tstr = scan.nextLine();String[] str = tstr.split("\\s+");String fname = str[0].substring(str[0].lastIndexOf("\\") + 1);fname = fname.substring(Math.max(fname.length() - 16, 0)) + " " + str[1]; //max 最快推荐 ?:也可以 if太麻烦Integer tmp = map.get(fname); //get==null较快写法if (tmp == null) {map.put(fname, 1);} else {map.put(fname, tmp + 1);}}int count = 0;for (Map.Entry<String, Integer> it : map.entrySet()) {if (map.size() - count <= 8) {System.out.println(it.getKey() + " " + it.getValue());}count++;}}}
HJ20 密码验证合格程序
方法1:手动检查
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);StringBuilder sb = new StringBuilder();String str = null;while (scan.hasNext()) {str = scan.nextLine();char[] arr = str.toCharArray();boolean[] flag = new boolean[4];// 1. 长度没有超过8位if (arr.length < 9) {sb.append("NG").append("\n");continue;}// 2. 至少有3种不同类型的符号for (int i = 0; i < arr.length; i++) {if ('A' <= arr[i] && arr[i] <= 'Z') {flag[0] = true;} else if ('a' <= arr[i] && arr[i] <= 'z') {flag[1] = true;} else if ('0' <= arr[i] && arr[i] <= '9') {flag[2] = true;} else {flag[3] = true;}}int count = 0;for (int i = 0; i < 4; i++) {if (flag[i]) {count++;}}// 3. 不能有长度大于2的包含公共元素的子串重复boolean sign = true;for (int i = 0; i < arr.length - 5; i++) {for (int j = i + 3; j < arr.length - 2; j++) {if (arr[i] == arr[j] && arr[i + 1] == arr[j + 1] && arr[i + 2] == arr[j + 2]) {sign = false;}}}if (count >= 3 && sign) {sb.append("OK").append("\n");} else {sb.append("NG").append("\n");}}System.out.println(sb);}}
方法2:正则表达式匹配
import java.util.*;import java.util.regex.*;public class Main {public static void main(String[] arg) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.next();if (str.length() <= 8) {System.out.println("NG");continue;}if (!getMatch(str)) {System.out.println("NG");continue;}if (hasDuplicatedString(str, 0, 3)) {System.out.println("NG");continue;}System.out.println("OK");}}// 2. 包括大小写字母.数字.其它符号,至少三种private static boolean getMatch(String str) {int count = 0;String[] regex = {"[a-z]", "[A-Z]", "[0-9]", "[^a-zA-Z0-9]"};for (int i = 0; i < regex.length; i++) {Pattern pattern = Pattern.compile(regex[i]);Matcher matcher = pattern.matcher(str);if (matcher.find()) {count++;}}return count >= 3;}// 3. 校验是否有重复子串private static boolean hasDuplicatedString(String str, int left, int right) {if (right >= str.length()) {return false;}if (str.substring(right).contains(str.substring(left, right))) {return true;} else {return hasDuplicatedString(str, left + 1, right + 1);}}}
HJ21 简单密码
方法1:直接按照规则进行变换
import java.util.*;public class Main {// 方法1:直接按照规则变换public static void main(String[] args) {Scanner scan = new Scanner(System.in);String str;while (scan.hasNext()) {str = scan.next();StringBuilder sb = new StringBuilder();for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);if (c >= 'A' && c < 'Z') {c = (char) (c - 'A' + 'b');} else if (c == 'Z') {c = 'a';} else if (c >= 'a' && c <= 'c') {c = '2';} else if (c >= 'd' && c <= 'f') {c = '3';} else if (c >= 'g' && c <= 'i') {c = '4';} else if (c >= 'j' && c <= 'l') {c = '5';} else if (c >= 'm' && c <= 'o') {c = '6';} else if (c >= 'p' && c <= 's') {c = '7';} else if (c >= 't' && c <= 'v') {c = '8';} else if (c >= 'w' && c <= 'z') {c = '9';}sb.append(c);}System.out.println(sb);}}}
方法2:哈希表
import java.util.*;public class Main {// 定义map容器,存储按键对应数字字符private static Map<String, String> map = new HashMap<>();// 静态初始化mapstatic {map.put("1", "1");map.put("abc", "2");map.put("def", "3");map.put("ghi", "4");map.put("jkl", "5");map.put("mno", "6");map.put("pqrs", "7");map.put("tuv", "8");map.put("wxyz", "9");map.put("0", "0");}public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.nextLine();char[] arr = str.toCharArray();StringBuilder sb = new StringBuilder();for (char c : arr) {if (c >= '0' && c <= '9') {sb.append(c);} else if (c >= 'A' && c <= 'Y') { // 如果是A~Y的大写字母则需要将其+32位转换成小写再向后移1位char newChar = (char) (c + 32 + 1);sb.append(newChar);} else if (c == 'Z') { // 如果是Z,则加密成asb.append("a");} else {Set<String> keys = map.keySet();for (String key : keys) {if (key.contains(String.valueOf(c)))sb.append(map.get(key));}}}System.out.print(sb.toString());}}}
HJ22 汽水瓶问题
描述
某商店规定:三个空汽水瓶可以换一瓶汽水,允许向老板借空汽水瓶(但是必须要归还)。
小张手上有n个空汽水瓶,她想知道自己最多可以喝到多少瓶汽水。
数据范围:输入的正整数满足 1 \le n \le 100 \1≤n≤100
注意:本题存在多组输入。输入的 0 表示输入结束,并不用输出结果。
输入描述:
输入文件最多包含 10 组测试数据,每个数据占一行,仅包含一个正整数 n( 1<=n<=100 ),表示小张手上的空汽水瓶数。n=0 表示输入结束,你的程序不应当处理这一行。
输出描述:
对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。
递归问题
根据题意可得:
拿出2个瓶子、再向老板借1个空瓶,换来一瓶水,喝完后把空瓶还给老板,也就是说用2个空瓶可以喝到1瓶水,所以可以总结递推公式:f(n) = f(n - 2) + 1;也可以直接推理出 n / 2 就是结果。
方法1:递归
import java.util.*;public class Main {// 方法1:递归public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int n = scan.nextInt();if (n == 0) {return;}int m = drink(n);System.out.println(m);}}public static int drink(int n) {if (n == 1) {return 0;}if (n == 2) {return 1;}return drink(n - 2) + 1;}}
方法2:直接计算。
import java.util.*;public class Main {// 方法2:直接计算结果public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int n = scan.nextInt();if (n == 0) {return;}System.out.println(n / 2);}}}
HJ23 删除字符串中出现次数最少的字符
方法1:哈希表。
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while(scan.hasNext()){String str = scan.nextLine();// 1. 数组做哈希表,统计每个字符出现的次数int[] arr = new int[26];for (int i = 0; i < str.length(); i++) {int index = str.charAt(i) - 'a';arr[index]++;}// 2. 找到出现次数最小的次数int min = Integer.MAX_VALUE;for (int i = 0; i < 26; i++) {if (arr[i] != 0 && arr[i] < min) {min = arr[i];}}// 3. 再次遍历字符串,过滤出现次数最少的字符StringBuilder sb = new StringBuilder();for (int i = 0; i < str.length(); i++) {int index = str.charAt(i) - 'a';if (arr[index] != min) {sb.append(str.charAt(i));}}System.out.println(sb);}}}
HJ26 字符串排序
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.nextLine();// 1. 筛选出字母添加到list集合中,大小写紧挨着List<Character> list = new ArrayList<>();for (int i = 'A'; i <= 'Z'; i++) {for (int j = 0; j < str.length(); j++) {char c = str.charAt(j);if (c == i || c == i + 32) { // 该字母的大写或小写list.add(c);}}}// 2. 遍历字符串,找到非字母字符,插入到list 集合对应位置for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);if (! Character.isLetter(c)) {list.add(i, c);}}// 3. list集合转字符串StringBuilder sb = new StringBuilder(str.length());for(Character c : list){sb.append(c);}System.out.println(sb);}}}
HJ27 查找兄弟单词
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {// 1. 前期处理,读取各项数据int N = scan.nextInt();String[] str = new String[N];for (int i = 0; i < N; i++) { // 输入n个单词作为字典单词str[i] = scan.next();}String findStr = scan.next(); // 输入一个待查单词int count = scan.nextInt(); // 输入待查单词的 指定序号// 2. 查找兄弟单词ArrayList<String> list = new ArrayList<>();for (int i = 0; i < N; i++) {// 长度相等,且字面值不相等if ((str[i].length() == findStr.length()) && (!str[i].equals(findStr))) {if (checkBorther(findStr, str[i])) {list.add(str[i]);}}}// 3. 输出Collections.sort(list);System.out.println(list.size());if (list.size() >= count) {System.out.println(list.get(count - 1));}}}// 判断两个字符串是否是兄弟单词public static boolean checkBorther(String str1, String str2) {// 桶排序思想int[] flag = new int[26];char[] ch1 = str1.toCharArray();char[] ch2 = str2.toCharArray();for (int i = 0; i < ch1.length; i++) {flag[ch1[i] - 'a']++;flag[ch2[i] - 'a']--;}for (int i = 0; i < 26; i++) {if (flag[i] != 0) {return false;}}return true;}}
HJ28 素数伴侣
方法1:匈牙利配对法
import java.util.*;public class Main {// 方法1:public static void main(String[] args) throws Exception {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {// 1. 读取数据int count = scan.nextInt();int[] arr = new int[count];for (int i = 0; i < count; i++) {arr[i] = scan.nextInt();}// 2. 元素奇偶分开ArrayList<Integer> evens = new ArrayList<>();ArrayList<Integer> odds = new ArrayList<>();for (int i = 0; i < count; i++) {if (arr[i] % 2 == 1) {odds.add(arr[i]);} else {evens.add(arr[i]);}}// 3. 奇偶配对 匈牙利配对法int result = 0;// 记录偶数配对的奇数伴侣的index(基1)int[] eventPairs = new int[evens.size() ];for (int i = 0; i < odds.size(); i++) {boolean[] used = new boolean[evens.size()];if (findPair(i, odds, evens, eventPairs, used)) {result++;}}System.out.println(result);}}public static boolean findPair(int oddIndex, ArrayList<Integer> odds, ArrayList<Integer> evens, int[] eventPairs, boolean[] used) {for (int i = 0; i < evens.size(); i++) {// 该偶数没有被使用过,且符合匹配规则if (!used[i] && isPrime(odds.get(oddIndex) + evens.get(i) )) {used[i] = true;if (eventPairs[i] == 0 || findPair(eventPairs[i] - 1, odds, evens, eventPairs, used)) {eventPairs[i] = oddIndex + 1;return true;}}}return false;}// 判断是否为素数public static boolean isPrime(int num) {// 1. 特殊情况 2,3if (num <= 3) {return num > 1;}// 2. 只有每个6X-1 和 6X+1可能为质数if (num % 6 != 1 && num % 6 != 5) {return false;}double sqrt = Math.sqrt(num);// 判断每个 6X-1 和 6X+1for (int i = 5; i < sqrt; i += 6) {if (num % i == 0 || num % (i + 2) == 0) {return false;}}return true;}}
HJ29 字符串加解密
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {System.out.println(encode(scan.nextLine()));System.out.println(decode(scan.nextLine()));}}// 加密函数private static String encode(String code) {char[] arr = code.toCharArray();for (int i = 0; i < arr.length; i++) {if (arr[i] >= 'a' && arr[i] < 'z')arr[i] = (char) (arr[i] - 'a' + 'A' + 1);else if (arr[i] == 'z')arr[i] = 'A';else if (arr[i] >= 'A' && arr[i] < 'Z')arr[i] = (char) (arr[i] - 'A' + 'a' + 1);else if (arr[i] == 'Z')arr[i] = 'a';else if (arr[i] >= '0' && arr[i] < '9')arr[i] = (char) (arr[i] + 1);else if (arr[i] == '9')arr[i] = '0';}return String.valueOf(arr);}// 解密函数private static String decode(String password) {char[] arr = password.toCharArray();for (int i = 0; i < arr.length; i++) {if (arr[i] > 'a' && arr[i] <= 'z')arr[i] = (char) (arr[i] - 'a' + 'A' - 1);else if (arr[i] == 'a')arr[i] = 'Z';else if (arr[i] > 'A' && arr[i] <= 'Z')arr[i] = (char) (arr[i] - 'A' + 'a' - 1);else if (arr[i] == 'A')arr[i] = 'z';else if (arr[i] > '0' && arr[i] <= '9')arr[i] = (char) (arr[i] - 1);else if (arr[i] == '0')arr[i] = '9';}return String.valueOf(arr);}}
HJ31 单词倒排
方法1:正则表达式分割
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.nextLine();String res = reverse(str);System.out.println(res);}}public static String reverse(String str) {// 正则表达式匹配非字母的字符String[] arr = str.split("[^A-Za-z]");StringBuilder sb = new StringBuilder();// 逆序添加for (int i = arr.length - 1; i >= 0; i--) {sb.append(arr[i]).append(" ");}return sb.toString().trim();}}
HJ33 整数与IP地址间的转换
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.next();String res;if (str.contains(".")) {res = ip2num(str);} else {res = num2ip(str);}System.out.println(res);}}// IP转数字,注意进制转化private static String ip2num(String str) {String[] arr = str.split("\\.");long result = 0;for (int i = 0; i < 4; i++) {result = result * 256 + Integer.parseInt(arr[i]);System.out.println(result);}return "" + result;}// 数字转IP,注意字符串拼接顺序private static String num2ip(String str) {long ipv4 = Long.parseLong(str);String res = "";for (int i = 0; i < 4; i++) {int num = (int) (ipv4 % 256);res = num + "." + res;ipv4 /= 256;}return res.substring(0, res.length() - 1);}}
HJ34 图片整理
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int bucket[] = new int[128];String str = scan.next();// 1. 字符映射数组的下标for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);bucket[c]++;}// 2. 打印for (int i = 48; i < bucket.length; i++) { // 从'0'开始输出if (bucket[i] != 0) {for (int j = 0; j < bucket[i]; j++) {System.out.print((char) i);}}}System.out.println();}}}
HJ35 三角矩阵
方法1:总结出数列规律。
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int n = scan.nextInt();StringBuilder sb = new StringBuilder();for (int row = 1; row <= n; row++) {// 1. 按行处理,元素为 (j * j + j) / 2for (int j = 1; j < n - (row - 1); j++) {int num = (j + row - 1);int value = (num * num + num) / 2 - (row - 1);sb.append(value).append(" ");}// 2. 添加每行末尾的元素int end = (n * n + n) / 2 - (row - 1);sb.append(end).append("\n");}System.out.println(sb);}}}
HJ36 字符串加密
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String key = scan.next().toLowerCase();String s = scan.next();ArrayList<Character> list = new ArrayList<>();// 如果list中不存在就放入for (int i = 0; i < key.length(); i++) {if (!list.contains(key.charAt(i))) {list.add(key.charAt(i));}}// 将A-Z放入到list中for (int i = 97; i <= 122; i++) {char c = (char) i;if (!list.contains(c)) {list.add(c);}}Map<Character, Character> map = new HashMap<>();int begin = 97;for (int i = 0; i < list.size(); i++) {map.put((char) (begin + i), list.get(i));}StringBuilder sb = new StringBuilder();for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);Character character = map.get(c);if (s.charAt(i) >= 97 && s.charAt(i) <= 122) {sb.append(character);} else {sb.append(Character.toUpperCase(character));}}System.out.println(sb.toString());}}}
HJ37 数兔子
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int n = scan.nextInt();System.out.println(countRabbit(n));}}public static int countRabbit(int n) {if (n == 1 || n == 2) {return 1;}return countRabbit(n - 1) + countRabbit(n - 2);}}
HJ38 小球落地反弹总路程
如图所示:假设从地面弹起到高度h,这样计算简单,最后再减去h就可以了。
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int h = scan.nextInt();double temp = h;double sum = 0;// 1. 假设小球从地上弹起到初始高度h,再落下来计算for (int i = 0; i < 5; i++) {sum += temp * 2;temp = temp / 2;}// 2. 减掉第一次假设弹上来的高度hsum -= h;System.out.printf("%.6f\n", sum);System.out.printf("%.6f\n", temp);}}}
HJ40 统计四种字符个数
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.nextLine();int letters = 0;int spaces = 0;int digits = 0;int others = 0;for (int i = 0; i < str.length(); i++) {char c = str.charAt(i);if (Character.isLetter(c)) {letters++;} else if (Character.isDigit(c)) {digits++;} else if (Character.isSpaceChar(c)) {spaces++;} else {others++;}}System.out.println(letters);System.out.println(spaces);System.out.println(digits);System.out.println(others);}}}
HJ41 砝码可称量的重量
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int n = scan.nextInt();int[] weight = new int[n];int[] nums = new int[n];for (int i = 0; i < n; i++) {weight[i] = scan.nextInt();}for (int i = 0; i < n; i++) {nums[i] = scan.nextInt();}int count = fama(n, weight, nums);System.out.println(count);}scan.close();}public static int fama(int n, int[] weight, int[] nums) {// 1. 先往set中添加第一个砝码可称量出来的重量Set<Integer> set = new HashSet<>();for (int i = 0; i <= nums[0]; i++) {set.add(weight[0] * i);}// 2. 遍历其他砝码,得到当前这个型号的砝码可称量的重量,添加到set中for (int i = 1; i < n; i++) {List<Integer> list = new ArrayList<>(set);for (int j = 0; j <= nums[i]; j++) {// 遍历上一刻的集合,把新的重量添加进去for (int k = 0; k < list.size(); k++) {int newWeight = weight[i] * j;set.add(list.get(k) + newWeight);}}}return set.size();}}
HJ43 迷宫问题
描述:定义一个二维数组 N*M ,如 5 × 5 数组下所示:
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。
本题含有多组数据,输入的内容只包含0~1
输入描述:输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
输出描述:
左上角到右下角的最短路径,格式如样例所示。
迷宫的例子
int[][] maze = {{0, 1, 0, 0, 0},{0, 1, 1, 1, 0},{0, 0, 0, 0, 0},{0, 1, 1, 1, 0},{0, 0, 0, 1, 0}};
方法1:回溯算法。
思考:下图就是代码的运行轨迹,要多在脑海中想象。
这是在某个位置,当四个方向上遍历结束时,打印当前path里面存储的路径结点。
当前坐标:[3 ,4] (0,0)-->(1,0)-->(2,0)-->(2,1)-->(2,2)-->(2,3)-->(2,4)-->(3,4)-->(4,4)当前坐标:[0 ,2] (0,0)-->(1,0)-->(2,0)-->(2,1)-->(2,2)-->(2,3)-->(2,4)-->(3,4)-->(1,4)-->(0,4)-->(0,3)-->(0,2)当前坐标:[0 ,3] (0,0)-->(1,0)-->(2,0)-->(2,1)-->(2,2)-->(2,3)-->(2,4)-->(3,4)-->(1,4)-->(0,4)-->(0,3)当前坐标:[0 ,4] (0,0)-->(1,0)-->(2,0)-->(2,1)-->(2,2)-->(2,3)-->(2,4)-->(3,4)-->(1,4)-->(0,4)当前坐标:[1 ,4] (0,0)-->(1,0)-->(2,0)-->(2,1)-->(2,2)-->(2,3)-->(2,4)-->(3,4)-->(1,4)当前坐标:[2 ,4] (0,0)-->(1,0)-->(2,0)-->(2,1)-->(2,2)-->(2,3)-->(2,4)-->(3,4)当前坐标:[2 ,3] (0,0)-->(1,0)-->(2,0)-->(2,1)-->(2,2)-->(2,3)-->(2,4)当前坐标:[2 ,2] (0,0)-->(1,0)-->(2,0)-->(2,1)-->(2,2)-->(2,3)当前坐标:[2 ,1] (0,0)-->(1,0)-->(2,0)-->(2,1)-->(2,2)当前坐标:[4 ,2] (0,0)-->(1,0)-->(2,0)-->(2,1)-->(3,0)-->(4,0)-->(4,1)-->(4,2)当前坐标:[4 ,1] (0,0)-->(1,0)-->(2,0)-->(2,1)-->(3,0)-->(4,0)-->(4,1)当前坐标:[4 ,0] (0,0)-->(1,0)-->(2,0)-->(2,1)-->(3,0)-->(4,0)当前坐标:[3 ,0] (0,0)-->(1,0)-->(2,0)-->(2,1)-->(3,0)当前坐标:[2 ,0] (0,0)-->(1,0)-->(2,0)-->(2,1)当前坐标:[1 ,0] (0,0)-->(1,0)-->(2,0)当前坐标:[0 ,0] (0,0)-->(1,0)
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int n = scan.nextInt();int m = scan.nextInt();// 1. 创建迷宫数组,从控制台读取数据并初始化数组int[][] maze = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {maze[i][j] = scan.nextInt();}}// 2. 创建两个list,分别存储一条路径和所有路径ArrayList<int[]> path = new ArrayList<>();ArrayList<ArrayList<int[]>> ret = new ArrayList<>();// 3. DFS,深度优先搜索dfsMazePath(maze, 0, 0, path, ret);// 4. 找到结果集中最短的路径int minIndex = 0;for (int i = 0; i < ret.size(); i++) {if (ret.get(i).size() < ret.get(minIndex).size()) {minIndex = i;}}// 5. 按题目要求打印路径path = ret.get(minIndex);for (int i = 0; i < path.size(); i++) {int[] arr = path.get(i);System.out.println("(" + arr[0] + "," + arr[1] + ")");}}}public static void dfsMazePath(int[][] maze, int i, int j, ArrayList<int[]> path, ArrayList<ArrayList<int[]>> ret) {// 1. 递归的终止条件:边界if (i < 0 || i > maze.length - 1 || j < 0 || j > maze[0].length - 1) {return;}// 2. 递归的终止条件:当前路径不可走,返回if (maze[i][j] == 1) {return;}// 3. 递归的终止条件:到达迷宫的终点if (i == maze.length - 1 && j == maze[0].length - 1) {int[] last = {i, j};path.add(last);ret.add(new ArrayList<>(path));return;}// 4. 当前路径可走,添加到path中,并把坐标设置为不可访问int[] cur = {i, j};path.add(cur);maze[i][j] = 1;// 5. 向四个方向进行探索dfsMazePath(maze, i, j + 1, path, ret); // 右dfsMazePath(maze, i + 1, j, path, ret); // 下dfsMazePath(maze, i, j - 1, path, ret); // 左dfsMazePath(maze, i - 1, j, path, ret); // 上// // 这段代码主要是用来查看DFS遍历的轨迹// System.out.print("当前坐标:" + "[" + i + " ," + j + "] ");// for (int k = 0; k < path.size(); k++) {// int[] tmp = path.get(k);// System.out.print("(" + tmp[0] + "," + tmp[1] + ")");// if (k != path.size() - 1) {// System.out.print("-->");// }// }// System.out.println();// 6. 回溯。path中移除最后一个坐标,并把当前坐标恢复成可访问path.remove(path.size() - 1);maze[i][j] = 0;}}
HJ52 编辑距离
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str1 = scan.nextLine();String str2 = scan.nextLine();int m = str1.length();int n = str2.length();// 1. 创建dp数组,并初始化边缘状态int[][] dp = new int[m + 1][n + 1];dp[0][0] = 0;for (int i = 1; i < dp.length; i++) {dp[i][0] = i;}for (int i = 1; i < dp[0].length; i++) {dp[0][i] = i;}// 2. 填充dp数组for (int i = 1; i < dp.length; i++) {for (int j = 1; j < dp[0].length; j++) {if (str1.charAt(i - 1) == str2.charAt(j - 1)) {dp[i][j] = dp[i - 1][j - 1];} else {int insertCost = dp[i][j - 1] + 1;int deleteCost = dp[i - 1][j] + 1;int replaceCost = dp[i - 1][j - 1] + 1;dp[i][j] = Math.min(insertCost, Math.min(deleteCost, replaceCost));}}}System.out.println(dp[m][n]);}}}
HJ53 杨辉三角的变形
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNextInt()) {int num = scan.nextInt();if (num == 1 || num == 2) {System.out.println(-1);} else if (num % 4 == 1 || num % 4 == 3) {System.out.println(2);} else if (num % 4 == 0) {System.out.println(3);} else if (num % 4 == 2) {System.out.println(4);}}}}
HJ54 表达式求值
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);String s = scan.nextLine();s = s.replace("{", "(");s = s.replace("[", "(");s = s.replace("}", ")");s = s.replace("]", ")");System.out.println(slove(s));}public static int slove(String s) {int len = s.length();char[] arr = s.toCharArray();int index = 0;char sign = '+';int number = 0;Stack<Integer> stack = new Stack<>();// 遍历字符串for (int i = 0; i < len; i++) {char ch = arr[i];// 1. 当前字符是空格,跳过if (ch == ' ') {continue;}// 2. 当前字符是数字,拼接数字if (Character.isDigit(ch)) {number = number * 10 + ch - '0';}// 3. 当前字符是小括号if (ch == '(') {int j = i + 1;int count = 1;while (count > 0) {if (arr[j] == ')') {count--;}if (arr[j] == '(') {count++;}j++;}// 递归,解小括号中的表达式number = slove(s.substring(i + 1, j - 1));i = j - 1;}// 4. 遇到符号,将数字处理后放进栈if (!Character.isDigit(ch) || i == len - 1) {if (sign == '+') {stack.push(number);} else if (sign == '-') {stack.push(-1 * number);} else if (sign == '*') {stack.push(stack.pop() * number);} else if (sign == '/') {stack.push(stack.pop() / number);}sign = ch;number = 0;}}// 5. 栈中数字求和得到结果int ans = 0;while (!stack.isEmpty()) {ans += stack.pop();}return ans;}}
HJ55 挑7
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int n = scan.nextInt();int count = 0;for (int i = 1; i <= n; i++) {if (i % 7 == 0) {count++;} else {String s = String.valueOf(i);if (s.contains("7")) {count++;}}}System.out.println(count);}}}
HJ56 完全数计算
import java.util.*;public class Main {// 参考:https://blog.nowcoder.net/n/9d96f4ca947f493b8c7632cddfd9cb24public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int num = scan.nextInt();int count = 0;for (int i = 2; i <= num; i++) {if (isPerfect(i)) {count++;}}System.out.println(count);}}public static boolean isPerfect(int n) {// 每个数都有因子 1int sum = 1;// 数学原理:一对因子总会分布在这个数的根号两边,或者就是这平方根值。for (int i = 2; i * i <= n; i++) {// 如果能被整除if (n % i == 0) {int quotient = n / i; // 整除得到的商if (quotient == i) { // 商和除数一样sum = sum + i;} else {sum = sum + i + quotient; // 不为平方根时,加上两个因子}}}return sum == n;}}
HJ60 查找组成一个偶数最接近的两个素数
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int n = scan.nextInt();// 最接近的素数,就从数的中间开始for (int i = n / 2; i >= 2; i--) {if (isPrime(i) && isPrime(n - i)) {System.out.println(i);System.out.println(n - i);break;}}}}public static boolean isPrime(int n) {// 素数 除了1和它本身的数,都不能被整除,所以要从2 开始到小于nfor (int i = 2; i < n; i++) {if (n % i == 0) {return false;}}return true;}}
HJ62 二进制中1的个数
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int n = scan.nextInt();int count = 0;while (n != 0) {n = n & (n - 1);count++;}System.out.println(count);}}}
HJ63 DNA序列
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.nextLine();int n = scan.nextInt();double len = 0.0;String result = "";for (int i = 0; i < str.length() - n + 1; i++) {String aim = str.substring(i, i + n);String res = aim.replaceAll("[^CG]", "");double cur = (double) res.length() / (double) n;if (cur > len) {len = cur;result = aim;}}System.out.println(result);}}}
HJ65 最长公共子串
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String s1 = scan.nextLine();String s2 = scan.nextLine();// 题目要求特殊:输出在较短串中最先出现的那个String temp = "";if (s1.length() > s2.length()) {temp = s1;s1 = s2;s2 = temp;}System.out.println(lcs(s1, s2));}}// 动态规划public static String lcs(String str1, String str2) {int m = str1.length();int n = str2.length();// 1. 创建dp数组// dp[i][j] 表示以str1第i个字符结尾,同时在str2中第j 个字符结尾时的公共子串长度int[][] dp = new int[m + 1][n + 1];int maxLen = 0;int end = 0;// 2. 填充dp数组for (int i = 1; i <= m; i++) {for (int j = 1; j <= n; j++) {// 3. 从头开始比较两个字符串,// 如果当前两个字符相同,长度就在上一个基础上加1// 如果不相同,公共子串就断开了,dp[i][j] = 0,因为初始化默认是0,所以不用重新赋值if (str1.charAt(i - 1) == str2.charAt(j - 1)) {dp[i][j] = dp[i - 1][j - 1] + 1;// 4. 更新记录最大的长度if (dp[i][j] > maxLen) {maxLen = dp[i][j];// end 记录最长公共子串尾部字符的索引坐标end = i - 1;}}}}// 5. 截取最长公共子串,[end - maxLen + 1, end + 1)return str1.substring(end - maxLen + 1, end + 1);}}
HJ67 24点
这个题有点意思,原来还是用DFS来做的,有想过打印出一个完整的算式,但做了半天没做出来,以后再看看吧。
import java.util.*;public class Main {// 全局变量static boolean flag = false;public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String[] s = scan.nextLine().split(" ");int[] arr = new int[4];boolean[] visit = new boolean[4];for (int i = 0; i < 4; i++) {arr[i] = Integer.parseInt(s[i]);}dfs(arr, 0, 0, visit);System.out.println(flag);}}private static boolean dfs(int[] arr, int count, float num, boolean[] visit) {if (count == 4 && num == 24) {flag = true;return true;}for (int i = 0; i < 4; i++) {if (visit[i] == false) {visit[i] = true;if (dfs(arr, count + 1, num + arr[i], visit) ||dfs(arr, count + 1, num - arr[i], visit) ||dfs(arr, count + 1, num * arr[i], visit) ||dfs(arr, count + 1, num / arr[i], visit)) {return true;}visit[i] = false;}}return false;}}
HJ72 百钱买百鸡问题
import java.util.*;public class Main {public static void main(String[] args) {// 鸡翁值5, 一百块最多买20只 鸡翁买x只// 鸡母值3, 一百块最多买33只 鸡母买y只// 鸡雏三值1, 一百块最多买300只 鸡雏买z只Scanner scan = new Scanner(System.in);// 买x鸡翁,y只鸡母,z只鸡雏// 5x + 3y + z/3 = 100 ==> 15x + 9y + z = 300// x + y + z = 100 加上面式子 ==> 14x + 8y = 200 ==> 7x + 4y = 100 ==> y = (100 - 7x)/4while (scan.hasNextInt()) {int n = scan.nextInt();for (int x = 0; x <= 14; x++) {if ((100 - 7 * x) % 4 == 0) {int y = (100 - 7 * x) / 4;int z = 100 - x - y;System.out.println(x + " " + y + " " + z);}}}}}
HJ76 尼科彻斯定理
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNextInt()) {int num = scan.nextInt();long sum = (long) Math.pow(num, 3);int a1 = (int) sum / num - (num - 1);StringBuilder sb = new StringBuilder();sb.append(a1);for (int i = 1; i < num; i++) {a1 = a1 + 2;sb.append("+");sb.append(a1);}System.out.println(sb);}}}
HJ77 火车进站
题目没看懂,代码也只是大概看了下。
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {int n = scan.nextInt();// 未进站的火车Queue<Integer> queue = new LinkedList<>();// 已进站的火车Stack<Integer> stack = new Stack<>();for (int i = 0; i < n; i++) {queue.offer(scan.nextInt());}List<String> outQueueList = new ArrayList<>();// 获取所有出站队列保存到outQueueListprocessOutQueue(queue, stack, "", outQueueList);// 排序后输出Collections.sort(outQueueList);for (String str : outQueueList) {System.out.println(str);}}}private static void processOutQueue(Queue<Integer> queue, Stack<Integer> stack, String outQueue, List<String> list) {// 1. 递归的终止条件:如果队列和栈都为空,则保存出站信息if (queue.isEmpty() && stack.isEmpty()) {list.add(outQueue.trim());return;}// 2. 出栈if (!stack.isEmpty()) {// 先克隆Queue<Integer> tempQueue = new LinkedList<>(queue);Stack<Integer> tempStack = (Stack<Integer>) stack.clone();String tempOutQueue = outQueue + (tempStack.pop() + " ");processOutQueue(tempQueue, tempStack, tempOutQueue, list);}// 3. 队列入队if (!queue.isEmpty()) {// 先克隆Queue<Integer> tempQueue = new LinkedList<>(queue);Stack<Integer> tempStack = (Stack<Integer>) stack.clone();tempStack.push(tempQueue.poll());processOutQueue(tempQueue, tempStack, outQueue, list);}}}
HJ84 统计大写字母个数
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String str = scan.nextLine();// 使用正则表达式特别方便,这句代码意思是把所有非大写字母替换为空String res = str.replaceAll("[^A-Z]", "");System.out.println(res.length());}}}
HJ86 二进制中最长连续1
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNextInt()) {int num = scan.nextInt();int maxLen = 0;int count = 0;while (num != 0) {// 1. 当前二进制数字末尾是1,和1做&运算,会得到1if ((num & 1) == 1) {count++;maxLen = Math.max(maxLen, count);} else {// 2. 当前二进制是0,就把cont重新设置为0count = 0;}// 3. 无符号右移num >>>= 1;}System.out.println(maxLen);}}}
HJ92 连续最长的数字串
import java.util.*;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);while (sc.hasNextLine()) {String str = sc.nextLine();int len = str.length();int[] dp = new int[len + 1];int maxLen = 0;for (int i = 1; i <= len; i++) {char c = str.charAt(i - 1);if (c >= '0' && c <= '9') {dp[i] = dp[i - 1] + 1;maxLen = Math.max(maxLen, dp[i]);}}for (int i = 1; i <= len; i++) {if (dp[i] == maxLen) {System.out.print(str.substring(i - maxLen, i));}}System.out.println("," + maxLen);}}}
HJ96 数字首尾加符号
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);while (scan.hasNext()) {String input = scan.next();String str = input.replaceAll("([0-9]+)", "*$1*");System.out.println(str);}}}
