- 入门
- 简单
- HJ1 字符串最后一个单词的长度
- HJ2 计算某字符出现次数
- HJ4 字符串分隔
- 55555 - HJ5 进制转换
- 55555 - HJ6 质数因子
- 55555 - HJ8 合并表记录
- HJ10 字符个数统计
- HJ11 数字颠倒
- HJ12 字符串反转
- HJ13 句子逆序
- 55555 - HJ14 字符串排序
- 55555 - HJ15 求int型正整数在内存中存储时1的个数
- 55555 - HJ21 简单密码
- HJ22 汽水瓶
- HJ23 删除字符串中出现次数最少的字符
- HJ31 单词倒排
- HJ34 图片整理
- HJ35 蛇形矩阵 - 1111122222
- 55555 - HJ37 统计每个月兔子的总数
- 55555 - HJ40 统计字符
- HJ51 输出单向链表中倒数第k个结点
- HJ53 杨辉三角的变形 - 1111122222
- 55555 - HJ54 表达式求值 - HJ50 四则运算
- HJ56 完全数计算 - 0
- 55555 - HJ60 查找组成一个偶数最接近的两个素数
- HJ61 放苹果 - 11111
- HJ62 查找输入整数二进制中1的个数 - 0
- HJ72 百钱买百鸡问题 - 1
- 55555 - HJ73 计算日期到天数转换
- 55555 - HJ76 尼科彻斯定理
- HJ80 整型数组合并 - 0
- 55555 - HJ81 字符串字符匹配
- HJ83 二维数组操作
- HJ84 统计大写字母个数 - 0
- 55555 - HJ85 最长回文子串
- 55555 - HJ86 求最大连续bit数
- 55555 - HJ87 密码强度等级
- HJ91 走方格的方案数 - 0
- HJ94 记票统计 - 11111
- HJ96 表示数字 - 0
- HJ97 记负均正 - 0
- HJ99 自守数 - 0
- 55555 - HJ100 等差数列
- 55555 - HJ102 字符统计
- 55555 - HJ105 记负均正II
- HJ106 字符逆序
- HJ108 求最小公倍数 - 11111
- 中等
- 66666 - HJ16 购物单
- 55555 - HJ17 坐标移动
- HJ20 密码验证合格程序 - 11111
- HJ24 合唱队 - 1
- 55555 - HJ26 字符串排序
- 55555 - HJ27 查找兄弟单词
- 55555 - HJ29 字符串加解密
- HJ32 密码截取
- 55555 - HJ33 整数与IP地址间的转换
- 55555 - HJ36 字符串加密
- HJ38 求小球落地5次后所经历的路程和第5次反弹的高度
- 66666 - HJ41 称砝码
- 66666 - HJ43 迷宫问题
- 55555 - HJ45 名字的漂亮度
- 55555 - HJ48 从单向链表中删除指定值的节点
- 55555 - HJ50 四则运算 - HJ54 表达式求值
- 55555 - HJ52 计算字符串的编辑距离
- HJ55 挑7
- 55555 - HJ57 高精度整数加法
- 55555 - HJ59 找出字符串中第一个只出现一次的字符
- 55555 - HJ63 DNA序列
- 55555 - HJ64 MP3光标位置
- 55555 - HJ65 查找两个字符串a,b中的最长公共子串
- 55555 - HJ66 配置文件恢复
- 55555 - 24点游戏算法
- 55555 - HJ69 矩阵乘法 - 11111
- 55555 - HJ70 矩阵乘法计算量估算
- 55555 - HJ71 字符串通配符
- HJ74 参数解析 - 1
- 55555 - HJ75 公共子串计算
- 55555 - HJ77 火车进站
- HJ82 将真分数分解为埃及分数 - 11111
- 55555 - HJ90 合法IP
- 55555 - HJ92 在字符串中找出连续最长的数字串
- 55555 - HJ103 Redraiment的走法
- 55555 - HJ107 求解立方根
- 较难
- 困难
https://blog.csdn.net/weixin_43428283/article/details/127361330
https://blog.csdn.net/fengyuyeguirenenen/article/details/125245803
https://blog.csdn.net/pengzongjy/category_12114900.html
https://blog.csdn.net/misayaaaaa/article/details/126965954
入门
HJ7 取近似值
// https://www.nowcoder.com/practice/3ab09737afb645cc82c35d56a5ce802a
// 描述
// 写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于 0.5 ,向上取整;小于 0.5 ,则向下取整。
// 数据范围:保证输入的数字在 32 位浮点数范围内
// 输入描述:
// 输入一个正浮点数值
// 输出描述:
// 输出该数值的近似整数值
// 输入:5.5
// 输出:6
// 说明:
// 0.5>=0.5,所以5.5需要向上取整为6
// 输入:2.499
// 输出:2
// 说明:0.499<0.5,2.499向下取整为2
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
int result = 0;
double a = in.nextDouble();
// 获取小数后第一位数字,判断是否大于等于5
int b = (int)(a * 10) % 10;
if(b >= 5){
result = (int)a + 1;
}else{
result = (int)a;
}
System.out.println(result);
}
}
}
HJ9 提取不重复的整数
// https://www.nowcoder.com/practice/253986e66d114d378ae8de2e6c4577c1
// 描述
// 输入一个 int 型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。
// 保证输入的整数最后一位不是 0 。
// 数据范围: 1 ≤ n ≤ 10^8
// 输入描述:
// 输入一个int型整数
// 输出描述:
// 按照从右向左的阅读顺序,返回一个不含重复数字的新的整数
// 输入:9876673
// 输出:37689
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
int a = in.nextInt();
// HashSet元素乱序
// LinkedHashSet保证元素添加顺序(!!!)
// TreeSet元素按自然顺序排序
Set<Character> set = new LinkedHashSet<>();
String str = String.valueOf(a);
for(int i = str.length() - 1; i >= 0; i--){
set.add(str.charAt(i));
}
str = "";
for(Character ch : set){
str = str + ch;
}
System.out.println(Integer.parseInt(str));
}
}
}
HJ46 截取字符串
// https://www.nowcoder.com/practice/a30bbc1a0aca4c27b86dd88868de4a4a
// 描述
// 输入一个字符串和一个整数 k ,截取字符串的前k个字符并输出
// 数据范围:字符串长度满足 1 \le n \le 1000 \1≤n≤1000 , 1 \le k \le n \1≤k≤n
// 输入描述:
// 1.输入待截取的字符串
// 2.输入一个正整数k,代表截取的长度
// 输出描述:
// 截取后的字符串
// 输入:abABCcDEF
// 6
// 输出:abABCc
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) { // 注意 while 处理多个 case
String str = in.next();
int num = in.nextInt();
StringBuilder result = new StringBuilder();
for(int i = 0; i < num; i++){
result = result.append(str.charAt(i));
}
System.out.println(result);
}
}
}
55555 - HJ58 输入n个整数,输出其中最小的k个
// https://www.nowcoder.com/practice/69ef2267aafd4d52b250a272fd27052c
// 描述
// 输入n个整数,找出其中最小的k个整数并按升序输出
// 本题有多组输入样例
// 数据范围:1 ≤ n ≤ 1000,输入的整数满足1 ≤ val ≤ 10000
// 输入描述:
// 第一行输入两个整数n和k
// 第二行输入一个整数数组
// 输出描述:
// 从小到大输出最小的k个整数,用空格分开
// 输入:5 2
// 1 3 5 7 2
// 输出:1 2
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
// 必须使用nextLine,而不是next
String a = in.nextLine,而不是next();
String b = in.nextLine();
String[] as = a.split(" ");
int nums = Integer.parseInt(as[0]);
int k = Integer.parseInt(as[1]);
// 字符串数组 转 整数数组
String[] str = b.split(" ");
int[] ints = new int[str.length];
for(int i = 0; i < str.length; i++){
ints[i] = Integer.parseInt(str[i]);
}
Arrays.sort(ints);
for(int i = 0; i < k && i < nums; i++){
System.out.print(ints[i] + " ");
}
}
}
}
HJ101 输入整型数组和排序标识,对其元素按照升序或降序进行排序
// https://www.nowcoder.com/practice/dd0c6b26c9e541f5b935047ff4156309
// 描述
// 输入整型数组和排序标识,对其元素按照升序或降序进行排序
// 数据范围:1 ≤ n ≤ 1000,元素大小满足0 ≤ val ≤ 100000
// 输入描述:
// 第一行输入数组元素个数
// 第二行输入待排序的数组,每个数用空格隔开
// 第三行输入一个整数0或1。0代表升序排序,1代表降序排序
// 输出描述:
// 输出排好序的数字
// 输入:8
// 1 2 4 9 3 55 64 25
// 0
// 输出:1 2 3 4 9 25 55 64
// 输入:5
// 1 2 3 4 5
// 1
// 输出:
// 5 4 3 2 1
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
// 必须都使用in.nextLine()接收参数才行,不能一个使用in.nextLine(),其他使用in.next()
int nums = Integer.parseInt(in.nextLine());
String str = in.nextLine();
int flag = Integer.parseInt(in.nextLine());
// 字符串数组 转 整数数组
String[] strs = str.split(" ");
// 此处必须使用包装类,否则无法使用Arrays.sort进行降序排列
Integer[] ints = new Integer[nums];
for (int i = 0; i < nums; i++) {
ints[i] = Integer.parseInt(strs[i]);
}
if (flag == 0) {
Arrays.sort(ints);
} else {
Arrays.sort(ints, (o1, o2) -> o2 - o1);
}
for (int i = 0; i < nums; i++) {
System.out.print(ints[i] + " ");
}
}
}
}
简单
HJ1 字符串最后一个单词的长度
// https://www.nowcoder.com/practice/8c949ea5f36f422594b306a2300315da
// 描述
// 计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)
// 输入描述:
// 输入一行,代表要计算的字符串,非空,长度小于5000。
// 输出描述:
// 输出一个整数,表示输入字符串最后一个单词的长度。
// 示例1
// 输入:hello nowcoder
// 输出:8
// 说明:最后一个单词为nowcoder,长度为8
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
String[] st = str.split(" ");
int len1 = st[st.length - 1].length();
System.out.println(len1);
}
}
HJ2 计算某字符出现次数
// https://www.nowcoder.com/practice/a35ce98431874e3a820dbe4b2d0508b1
// 描述
// 写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中该字符的出现次数。(不区分大小写字母)
// 数据范围: 1 \le n \le 1000 \1≤n≤1000
// 输入描述:
// 第一行输入一个由字母、数字和空格组成的字符串,第二行输入一个字符(保证该字符不为空格)。
// 输出描述:
// 输出输入字符串中含有该字符的个数。(不区分大小写字母)
// 输入:ABCabc
// A
// 输出:2
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
String s = sc.nextLine();
int count = 0;
for(int i = 0; i < str.length(); i++){
if(s.equalsIgnoreCase(str.charAt(i) + "")){
count++;
}
}
System.out.println(count);
}
}
HJ4 字符串分隔
// https://www.nowcoder.com/practice/d9162298cb5a437aad722fccccaae8a7
// 描述
// • 输入一个字符串,请按长度为8拆分每个输入字符串并进行输出;
// • 长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。
// 输入描述:
// 连续输入字符串(每个字符串长度小于等于100)
// 输出描述:
// 依次输出所有分割后的长度为8的新字符串
// 输入:abc
// 输出:abc0000
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int len = str.length();
if (len % 8 == 0) {
for (int i = 0; i < len; i = i + 8) {
System.out.println(str.substring(i, i + 8));
}
} else {
int temp = len % 8;
for (int i = 0; i < 8 - temp; i++) {
str = str + "0";
}
len = str.length();
for (int i = 0; i < len; i = i + 8) {
System.out.println(str.substring(i, i + 8));
}
}
}
}
55555 - HJ5 进制转换
// https://www.nowcoder.com/practice/8f3df50d2b9043208c5eed283d1d4da6
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
// 八进制数以数字0开头、十六进制以0x开头
if(str.charAt(0) == '0'){
int number = Integer.parseInt(str.substring(2), 16);
System.out.println(number);
}else {
int number = Integer.parseInt(str, 16);
System.out.println(number);
}
}
}
}
55555 - HJ6 质数因子
// https://www.nowcoder.com/practice/196534628ca6490ebce2e336b47b3607
// 描述:功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )
// 输入描述:输入一个整数
// 输出描述:按照从小到大的顺序输出它的所有质数的因子,以空格隔开。
// 示例1
// 输入:180
// 输出:2 2 3 3 5
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
long num = in.nextLong();
// 一个正整数只有一个质因子是大于其平方根,这个质因子就是它本身
long k = (long) Math.sqrt(num);
for (long i = 2; i <= k; i++) {
while (num % i == 0) {
System.out.print(i + " ");
num = num / i;
}
}
System.out.println(num == 1 ? "": num + "");
}
}
}
55555 - HJ8 合并表记录
// https://www.nowcoder.com/practice/de044e89123f4a7482bd2b214a685201
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()){
int nums = in.nextInt();
// HashMap执行结果未按照index升序
// Map<Integer, Integer> map = new HashMap<>();
// TreeMap默认按照key进行升序排序,也可以自定义排序规则
Map<Integer, Integer> map = new TreeMap<>();
for (int i = 0; i < nums; i++) {
int key = in.nextInt();
int value = in.nextInt();
// map.put(key, map.getOrDefault(key, 0) + value);
if (map.containsKey(key)){
map.put(key, map.get(key) + value);
}else {
map.put(key, value);
}
}
// 遍历输出方式一:
// for(Integer key : map.keySet()){
// System.out.println(key + " " + map.get(key));
// }
// 遍历输出方式二:
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
}
public void test() {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
int nums = Integer.parseInt(in.nextLine());
// 使用数组会报错内存溢出
// int[] result = new int[11111112];
Map<Integer, Integer> map = new TreeMap<>();
for(int i = 0; i < nums; i++){
String b = in.nextLine();
String[] strs = b.split(" ");
int key = Integer.parseInt(strs[0]);
int value = Integer.parseInt(strs[1]);
// result[index] = result[index] + value;
if (map.containsKey(key)){
map.put(key, map.get(key) + value);
}else {
map.put(key, value);
}
}
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
}
}
HJ10 字符个数统计
// https://www.nowcoder.com/practice/eb94f6a5b2ba49c6ac72d40b5ce95f50
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) { // 注意 while 处理多个 case
String str = in.next();
Set<Character> set = new HashSet<>();
for(int i = 0; i < str.length(); i++){
char ch = str.charAt(i);
set.add(ch);
}
System.out.println(set.size());
}
}
}
HJ11 数字颠倒
// https://www.nowcoder.com/practice/ae809795fca34687a48b172186e3dafe
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
int num = in.nextInt();
String str = String.valueOf(num);
for(int i = str.length() - 1; i >= 0; i--){
System.out.print(str.charAt(i));
}
}
}
}
HJ12 字符串反转
// https://www.nowcoder.com/practice/e45e078701ab4e4cb49393ae30f1bb04
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) { // 注意 while 处理多个 case
String str = in.next();
for(int i = str.length() - 1; i >= 0; i--){
System.out.print(str.charAt(i));
}
}
}
}
HJ13 句子逆序
// https://www.nowcoder.com/practice/48b3cb4e3c694d9da5526e6255bb73c3
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 必须使用hasNextLine,而不能使用hasNext,使用hasNext,只会读取第一个字符串
while (in.hasNextLine()) {
String str = in.nextLine();
String[] strs = str.split(" ");
for(int i = strs.length - 1; i >= 0; i--){
System.out.print(strs[i] + " ");
}
}
}
}
55555 - HJ14 字符串排序
// https://www.nowcoder.com/practice/5af18ba2eb45443aa91a11e848aa6723
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
List<String> list = new ArrayList<>();
int num = in.nextInt();
for(int i = 0; i < num; i++){
String str = in.next();
list.add(str);
}
// 按照字典序排列
Collections.sort(list);
// 按照字典序逆序排列
Collections.sort(list, (o1, o2) -> o2.compareTo(o1));
for(String str : list){
System.out.println(str);
}
}
}
}
55555 - HJ15 求int型正整数在内存中存储时1的个数
进行转换 - 1
https://blog.csdn.net/besto229/article/details/75796033
https://blog.csdn.net/u012027907/article/details/77683813
// https://www.nowcoder.com/practice/440f16e490a0404786865e99c6ad91c9
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int number = in.nextInt();
// 将十进制数转换为二进制数
String binary = Integer.toBinaryString(number);
// 将十进制数转换为八进制数
String octal = Integer.toOctalString(number);
// 将十进制数转换为十六进制数
String hex = Integer.toHexString(number);
// 将其他进制数转换为十进制数,2表示需转换的字符串为二进制
int num = Integer.parseInt("100", 2); // 4
int count = 0;
for(int i = 0; i < binary.length(); i++){
if(binary.charAt(i) == '1') count++;
}
System.out.println(count);
}
}
// 方法二:
public void test() {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int number = in.nextInt();
//【1】需要一个长度为32的int数组来存储结果二进制
int[] bit = new int[32];
//【2】循环,把原始数除以2取得余数,这个余数就是二进制数,原始的数等于商。
// 商如果不能再除以二,结束循环。
int i = 0;
while(number > 1){
// 获取除以2的余数
int b = number % 2;
// 数字除以2的商 赋值给当前数字
number = number / 2;
bit[i++] = b;
if(number < 2){
// 已经不能再把数除以2,就把该数直接放到数组的下一位
bit[i+1] = number;
}
}
//【3】翻转数组,得到的才是最终二进制数组(此处求1的个数可以进行翻转,直接求值)
for(int j = 0; j < bit.length / 2; j++){
// 第一个数的值设置为最后一个数的值
// 第二次的时候,i是1,把第二个数的值,赋值为倒数第二个
int temp = bit[j];
bit[j] = bit[bit.length - 1 - j];
bit[bit.length - 1 - j] = temp;
}
int count = 0;
for(int k = 0; k < bit.length; k++){
if(bit[k] == 1) count++;
}
System.out.println(count);
}
}
}
55555 - HJ21 简单密码
// https://www.nowcoder.com/practice/7960b5038a2142a18e27e4c733855dac
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
// 定义map容器存储按键对应数字字符的容器
private static Map<String, String> map = new HashMap<>();
// 静态初始化、加载map容器
static{
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 scanner = new Scanner(System.in);
while(scanner.hasNext()){
String str = scanner.nextLine();
char[] chars = str.toCharArray();
// 构造buffer容器存储转换后的字符串
StringBuffer buffer = new StringBuffer();
for(char ch : chars){
//【1】小写字母转换为数字
if(ch >= 'a' && ch <= 'z'){
// map容器中的key与字符进行校验并加密
Set<String> keys = map.keySet();
for(String key : keys){
if(key.contains(String.valueOf(ch))){
buffer.append(map.get(key));
}
}
//【2】如果是A - Y的大写字母则需要将其+32位转换成小写再向后移1位
// 大写字母的ASCII范围:65-90
// 小写字母的ASCII范围:97-122
// 数字的ASCII范围:48-57
}else if(ch >= 'A' && ch <= 'Y'){
char newChar = (char)(ch + 32 + 1);
buffer.append(newChar);
//【2.1】如果是Z则加密成a
}else if(ch == 'Z'){
buffer.append("a");
//【3】数字和其它的符号都不做变换
}else{
buffer.append(ch);
}
}
System.out.print(buffer.toString());
}
}
public void test() {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
char[] chars = in.next().toCharArray();
// 明文密码
char[] char1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray();
// 明文密码 加密后的数组,根据索引与明文密码char1一一对应
char[] char2 = "bcdefghijklmnopqrstuvwxyza222333444555666777788899990123456789".toCharArray();
for(int i = 0; i < chars.length; i++){
// 大写字母转小写
if(chars[i] >= 'A' && chars[i] <= 'Z'){
chars[i] = char2[chars[i] - 'A'];
// 小写字母转数字。前面是26个小写字母,所以要从索引26开始
}else if(chars[i] >= 'a' && chars[i] <= 'z'){
chars[i] = char2[chars[i] - 'a' + 26];
}
}
StringBuilder result = new StringBuilder();
for(Character ch : chars){
result.append(ch);
}
System.out.println(result);
}
}
}
HJ22 汽水瓶
// https://www.nowcoder.com/practice/fe298c55694f4ed39e256170ff2c205f
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
int num = in.nextInt();
if(num == 0){
break;
}
int result = 0;
while(num > 1){
if(num == 2){
num++;
}
// 每轮循环获取的汽水瓶数:num/3
result = result + num / 3;
// 每轮循环后剩余的空瓶子数:新兑换的汽水形成的空瓶子 + 当前循环剩余的空瓶子
num = num / 3 + num % 3;
// if(num % 3 == 0){
// num = num / 3;
// result = result + num;
// }else if(num % 3 == 1){
// result = result + num / 3;
// num = num / 3 + 1;
// }else if(num % 3 == 2){
// result = result + num / 3;
// num = num / 3 + 2;
// }
}
System.out.println(result);
}
}
}
HJ23 删除字符串中出现次数最少的字符
// https://www.nowcoder.com/practice/05182d328eb848dda7fdd5e029a56da9
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
//【1】统计每个字母的数量
Map<Character, Integer> map = new HashMap<>();
for(int i = 0; i < str.length(); i++){
int value = map.getOrDefault(str.charAt(i), 0);
map.put(str.charAt(i), value + 1);
}
// //【2】找到数量最少的字符数量
// Collection<Integer> values = map.values();
// int min = Collections.min(values);
// //【3】用空字符串替换该字母
// for(Character ch : map.keySet()) {
// if (map.get(ch) == min){
// str = str.replaceAll(String.valueOf(ch), "");
// }
// }
// System.out.println(str);
//【2】找到数量最少的字符数量
int minConut = Integer.MAX_VALUE;
for (int times : map.values()) {
minConut = Math.min(minConut, times);
}
//【3】剔除最少数量的字符
StringBuilder res = new StringBuilder();
for(char ch : str.toCharArray()) {
if (map.get(ch) != minConut) {
res.append(ch);
}
}
System.out.println(res.toString());
// 需要有序的map对结果进行收集
// Map<Character, Integer> map1 = new LinkedHashMap<>();
// map.entrySet().stream().sorted((o1, o2) -> o1.getValue() - o2.getValue())
// .forEach(e -> map1.put(e.getKey(), e.getValue()));
}
}
public void test() {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
//【1】统计输入字符串中每个字符的个数(小写字母有32位)
int[] chars = new int[32];
for(int i = 0; i < str.length(); i++){
char ch = str.charAt(i);
chars[ch - 'a']++;
}
//【2】求出字符串中字符出现最少的数量
int min = Integer.MAX_VALUE;
for(int num : chars){
if(num > 0){
min = Math.min(min, num);
}
}
//【3】外层遍历输入的字符串,内层遍历字符对应的数量
StringBuffer result = new StringBuffer();
for(int i = 0; i < str.length(); i++){
for(int j = 0; j < chars.length; j++){
// 当遍历字符 与 数组下标对应字符相等,并且字符数量大于最小值时,加入结果集
if(str.charAt(i) == (char)(j + 97) && chars[j] > min){
result.append(str.charAt(i));
break;
}
}
}
System.out.println(result.toString());
}
}
}
HJ31 单词倒排
// https://www.nowcoder.com/practice/81544a4989df4109b33c2d65037c5836
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String str = in.nextLine();
for(int i = 0; i < str.length(); i++){
char ch = str.charAt(i);
if(ch >= 'a' && ch <= 'z'){
}else if(ch >= 'A' && ch <= 'Z'){
}else{
str = str.replace(ch, ' ');
}
}
String[] strs = str.split(" ");
for(int i = strs.length - 1; i >= 0; i--){
System.out.print(strs[i].trim() + " ");
}
}
}
}
HJ34 图片整理
// https://www.nowcoder.com/practice/2de4127fda5e46858aa85d254af43941
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
List<Character> list = new ArrayList<>();
for(int i = 0; i < str.length(); i++){
list.add(str.charAt(i));
}
Collections.sort(list);
for(Character ch : list){
System.out.print(ch);
}
}
}
}
HJ35 蛇形矩阵 - 1111122222
对角线赋值
// https://www.nowcoder.com/practice/649b210ef44446e3b1cd1be6fa4cab5e
// 蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形。
// 例如,当输入5时,应该输出的三角形为:
// 1 3 6 10 15
// 2 5 9 14
// 4 8 13
// 7 12
// 11
// 输入描述:输入正整数N(N不大于100)
// 输出描述:输出一个N行的蛇形矩阵
// 输入:4
// 输出:
// 1 3 6 10
// 2 5 9
// 4 8
// 7
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
int[][] result = new int[num][];
// 初始化第一个值
int value = 1;
for(int i = 0; i < num; i++){
// 第i行有n-i个元素
result[i] = new int[num - i];
for(int j = 0; j <= i; j++){
// 对第i个对角线赋值(从左下到右上赋值:行数依次向上减少、列数依次向右增加)
result[i-j][j] = value;
value++;
}
}
for(int[] rows : result){
for(int col : rows){
System.out.print(col + " ");
}
System.out.println();
}
}
}
}
55555 - HJ37 统计每个月兔子的总数
// https://www.nowcoder.com/practice/1221ec77125d4370833fd3ad5ba72395
// 有一种兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子。
// 例子:假设一只兔子第3个月出生,那么它第5个月开始会每个月生一只兔子。
// 一月的时候有一只兔子,假如兔子都不死,问第n个月的兔子总数为多少?
// 输入:3
// 输出:2
// 输入:5
// 输出:5
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
int k1 = 1; // 第一个月,刚出生的兔子数量
int k2 = 0; // 第二个月,不可生育的兔子数量
int k3 = 0; // 第三个月,可以生育的兔子数量
// 从第二个月开始,到第num个月结束
for(int i = 2; i <= num; i++){
// 每增加一个月,可以生育的兔子数量 = 先前可生育数量 + 先前不可生育数量
k3 = k3 + k2;
// 每增加一个月,不可生育的兔子数量 = 先前刚出生数量
k2 = k1;
// 每增加一个月,刚出生兔子数量 = 先前可以生育兔子数量
k1 = k3;
}
System.out.println(k1 + k2 + k3);
}
}
}
55555 - HJ40 统计字符
// https://www.nowcoder.com/practice/539054b4c33b4776bc350155f7abd8f5
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String str = in.nextLine();
// HashMap是无序的,LinkedHashMap是有序的,且默认为插入顺序
Map<String, Integer> map = new LinkedHashMap<>();
map.put("yinwen", 0);
map.put("kongge", 0);
map.put("shuzi", 0);
map.put("qita", 0);
for(int i = 0; i < str.length(); i++){
char ch = str.charAt(i);
if(ch >= 'a' && ch <= 'z'){
map.put("yinwen", map.getOrDefault("yinwen", 0) + 1);
}else if(ch >= 'A' && ch <= 'Z'){
map.put("yinwen", map.getOrDefault("yinwen", 0) + 1);
}else if(ch >= '0' && ch <= '9'){
map.put("shuzi", map.getOrDefault("shuzi", 0) + 1);
}else if(ch == ' '){
map.put("kongge", map.getOrDefault("kongge", 0) + 1);
}else{
map.put("qita", map.getOrDefault("qita", 0) + 1);
}
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getValue());
}
}
}
}
HJ51 输出单向链表中倒数第k个结点
// https://www.nowcoder.com/practice/54404a78aec1435a81150f15f899417d
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String num = in.nextLine();
String[] strs = in.nextLine().split(" ");
int target = Integer.parseInt(in.nextLine());
//【1】字符串数组 转换为 整数数组
int[] nums = new int[strs.length];
for(int i = 0; i < strs.length; i++){
nums[i] = Integer.parseInt(strs[i]);
}
//【2】构建单向链表,先构建尾结点,再从尾到头依次构建节点
ListNode lastNode = new ListNode(nums[nums.length-1], null);
ListNode head = lastNode;
for(int i = nums.length - 2; i >= 0; i--){
head = new ListNode(nums[i], lastNode);
lastNode = head;
}
ListNode slow = head;
ListNode fast = head;
//【3】从头到尾找到第k个节点
for(int i = 0; i < target; i++){
fast = fast.next;
}
//【4】同时移动快慢指针,当快指针到达尾部时,慢指针刚好指向倒数第k个节点(快慢指针之间距离始终保持k个节点)
while (fast != null){
fast = fast.next;
slow = slow.next;
}
System.out.println(slow.value);
}
}
}
class ListNode{
int value;
ListNode next;
public ListNode(){
}
public ListNode(int value, ListNode next){
this.value = value;
this.next = next;
}
}
HJ53 杨辉三角的变形 - 1111122222
// https://www.nowcoder.com/practice/8ef655edf42d4e08b44be4d777edbf43
// 以上三角形的数阵,第一行只有一个数1,以下每行的每个数,是恰好是它上面的数、左上角数和右上角的数,3个数之和(如果不存在某个数,认为该数就是0)。
// 求第n行第一个偶数出现的位置。如果没有偶数,则输出-1。例如输入3,则输出2,输入4则输出3,输入2则输出-1
// 输入描述:输入一个int整数
// 输出描述:输出返回的int值
// 输入:4
// 输出:3
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
// 规律:-1 -1 2 3 2 4 2 3 2 4 2 3 2 4 2 3 2 4 2 3 2 4......
if(num == 1 || num == 2){
System.out.println(-1);
}else if(num % 4 == 0){
System.out.println(3);
}else if((num-2) % 4 == 0){
System.out.println(4);
}else if(num % 4 == 1 || num % 4 == 3){
System.out.println(2);
}
}
}
}
55555 - HJ54 表达式求值 - HJ50 四则运算
// https://www.nowcoder.com/practice/9566499a2e1546c0a257e885dfdbf30d
// 输入:400+5
// 输出:405
https://blog.nowcoder.net/n/7d2b83a154964702889c14af4750a0e9?f=comment
https://blog.nowcoder.net/n/098ac570a79c42afa423edc79bb7c22b?f=comment
https://blog.nowcoder.net/n/3031988aa4d546ebb511b4b1743b7d46?f=comment
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意hasNext 和 hasNextLine的区别
while (in.hasNext()) {
String str = in.next();
str = str.replace("[", "(");
str = str.replace("{", "(");
str = str.replace("}", ")");
str = str.replace("]", ")");
System.out.println(slove(str));
}
}
public static int slove(String str) {
Stack<Integer> stack = new Stack<>();
char[] chars = str.toCharArray();
// 初始化符号为'+'
char sign = '+';
// 记录数字(主要是记录大于9的数字)
int number = 0;
for (int index = 0; index < str.length(); index++) {
char ch = chars[index];
//【1】当前字符是数字,拼接数字
if (Character.isDigit(ch)) {
number = number * 10 + (ch - '0');
}
//【2】当前字符是左括号
if (ch == '(') {
// 下标移动到括号后一位字符
int right = index + 1;
//【2.1】统计左括号的数量
int count = 1;
while (count > 0) {
if (chars[right] == '(') count++; // 遇到左括号,左括号数+1
if (chars[right] == ')') count--; // 遇到右括号,抵消一个左括号,形成闭环,左括号数-1
right++;
}
//【2.2】递归求解当前已经闭环括号中的表达式,每次递归都是将元素放入到的一个新栈中,返回值就是ans
// index+1:当前闭环括号的起始位置,index是第一个左括号位置
// right-1:当前闭环括号中最后一个右括号的位置,right是右括号的下一个字符位置
number = slove(str.substring(index+1, right-1));
// 因为for循环要index++,所以此处要先回退一步到最后一个右括号的位置
index = right - 1;
}
//【3】当前字符是运算符,或者通过步骤2、当前的index可能是字符串末尾上的右括号,将已知的数字处理后放进栈
if (!Character.isDigit(ch) || index == str.length() - 1) {
//【3.1】左边的符号若是'+', 直接放入栈
if (sign == '+') {
stack.push(number);
//【3.2】左边的符号若是'-', 数字取相反后,再放入栈
}else if (sign == '-') {
stack.push(-1 * number);
//【3.3】左边的符号若是'*', 将该数字与栈中弹出一个数字相乘后,再放入栈
}else if (sign == '*') {
stack.push(stack.pop() * number);
//【3.4】左边的符号若是'/', 栈中弹出一个数字与该数字相除后,再放入栈
}else if (sign == '/') {
stack.push(stack.pop() / number);
}
// 更新运算符
sign = ch;
// 当前数字已运算完毕,必须重置为0
number = 0;
}
}
// 栈中数字求和得到结果
int ans = 0;
while (!stack.isEmpty()) {
ans += stack.pop();
}
return ans;
}
}
HJ56 完全数计算 - 0
// https://www.nowcoder.com/practice/7299c12e6abb437c87ad3e712383ff84
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
int count = 0;
for(int index = 1; index <= num; index++){
int sum = 0;
for(int i = 1; i <= index / 2; i++){
// 判断i能否被index整除
if(index % i == 0){
sum = sum + i;
}
}
if(sum == index){
count++;
}
}
System.out.println(count);
}
}
}
55555 - HJ60 查找组成一个偶数最接近的两个素数
// https://www.nowcoder.com/practice/f8538f9ae3f1484fb137789dec6eedb9
// 任意一个偶数(大于2)都可以由2个素数组成,组成偶数的2个素数有很多种情况,
// 本题目要求输出组成指定偶数的两个素数差值最小的素数对
// 输入:20
// 输出:
// 7
// 13
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
// 两个素数差值最小的素数对:肯定位于靠近num中点,所以从中点开始遍历查找
// i越来越小,num-i就越来越大。i肯定不大于num-i
for(int i = num/2; i >= 2; i--){
if(isPrime(i) && isPrime(num - i)){
System.out.println(i);
System.out.println(num - i);
break;
}
}
}
}
// 判断素数的方法
public static boolean isPrime(int num){
for(int i = 2; i <= Math.sqrt(num); i++){
if(num % i == 0){
return false;
}
}
return true;
}
}
HJ61 放苹果 - 11111
// https://www.nowcoder.com/practice/bfd8234bb5e84be0b493656e390bdebf
// 把m个同样的苹果放在n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?
// 注意:如果有7个苹果和3个盘子,(5,1,1)和(1,5,1)被视为是同一种分法
// 数据范围:0 <= m <= 10,1 ≤ n ≤ 10
// 输入:7 3
// 输出:8
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int m = in.nextInt();
int n = in.nextInt();
//【1】dp[i][j]表示i个苹果、放入n个盘子中的放置方案
int[][] dp = new int[m+1][n+1];
//【2】若只有一个盘子,则只有一个放置方案
for(int i = 1; i <= m; i++){
dp[i][1] = 1;
}
//【3】若只有一个苹果、或者没有苹果,则只有一个分配方案
for(int j = 1; j <= n; j++){
dp[0][j] = 1;
dp[1][j] = 1;
}
for(int i = 2; i <= m; i++){
for(int j = 2; j <= n; j++){
if(i < j){
//【4.1】若苹果比盘子数量少,则一定存在空盘子,所以去除这些空盘子,不影响放置方案数
dp[i][j] = dp[i][i];
}else{
//【4.2】dp[i][j-1]:空置一个盘子,所有苹果只能放到j-1个盘子
// dp[i-j][j]:不空置盘子,所有盘子至少放一个苹果,等价于所有盘子都少放一个苹果的方案数
dp[i][j] = dp[i][j-1] + dp[i-j][j];
}
}
}
//【5】输出m个苹果放到n个盘子的放置方案数
System.out.println(dp[m][n]);
}
}
}
HJ62 查找输入整数二进制中1的个数 - 0
// https://www.nowcoder.com/practice/1b46eb4cf3fa49b9965ac3c2c1caf5ad
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
String binary = Integer.toBinaryString(num);
int count = 0;
for(int i = 0; i < binary.length(); i++){
if(binary.charAt(i) == '1'){
count++;
}
}
System.out.println(count);
}
}
}
HJ72 百钱买百鸡问题 - 1
// https://www.nowcoder.com/practice/74c493f094304ea2bda37d0dc40dc85b
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
// 15x + 9y + z = 300
// x + y + z = 100
// 14x + 8y = 200
// 7x + 4y = 100
// x -> [0, 20] y -> [0, 33]
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
// 看清楚题意:现要求你打印出所有花一百元买一百只鸡的方式,是打印100,而不是num
int num = in.nextInt();
for( int x = 0; x <= 100; x+=4){
int y = (100 - 7*x) / 4;
int z = 100 - x - y;
if((y >= 0 && y <= 100) && (z >= 0 && z <= 100)){
System.out.println(x + " " + y + " " + z);
}
}
// for(int x = 0; x < 20; x++){
// for(int y = 33; y >= 0; y--){
// if(7*x + 4*y == 100){
// int z = 100 - x - y;
// System.out.println(x + " " + y + " " + z);
// }
// }
// }
}
}
}
55555 - HJ73 计算日期到天数转换
// https://www.nowcoder.com/practice/769d45d455fe40b385ba32f97e7bcded
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String str = in.nextLine();
String[] strs = str.split(" ");
int year = Integer.valueOf(strs[0]);
int month = Integer.valueOf(strs[1]);
int day = Integer.valueOf(strs[2]);
int[] month_day = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int total = day;
// 累加当前月的前面所有整数月的天数
for(int i = 0; i < month - 1; i++){
total += month_day[i];
}
// 闰年且月份超过2月。单独加1天
if(month > 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)){
total += 1;
}
System.out.println(total);
}
}
public void test02() {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String str = in.nextLine();
String[] strs = str.split(" ");
int year = Integer.valueOf(strs[0]);
int month = Integer.valueOf(strs[1]);
int day = Integer.valueOf(strs[2]);
Calendar c1 = Calendar.getInstance(); // 实例化
c1.set(year, month-1, day); // 注意月份从0开始
System.out.println(c1.get(Calendar.DAY_OF_YEAR));
}
}
public void test01() {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String str = in.nextLine();
String[] strs = str.split(" ");
int year = Integer.valueOf(strs[0]);
int month = Integer.valueOf(strs[1]);
int day = Integer.valueOf(strs[2]);
int secondMonth = 29;
// 公历年份是4的倍数,且不是100的倍数,为普通闰年。公历年份是整百数,且必须是400的倍数才是世纪闰年
if(year % 4 != 0 || (year % 100 == 0 && year % 400 != 0)){
secondMonth = 28;
}
if(month == 1){
System.out.println(day);
}
else if(month == 2){
System.out.println(day + 31);
}
else if(month == 3){
System.out.println(day + 31 + secondMonth);
}
else if(month == 4){
System.out.println(day + 31 + secondMonth + 31);
}
else if(month == 5){
System.out.println(day + 31 + secondMonth + 31 + 30);
}
else if(month == 6){
System.out.println(day + 31 + secondMonth + 31 + 30 + 31);
}
else if(month == 7){
System.out.println(day + 31 + secondMonth + 31 + 30 + 31 + 30);
}
else if(month == 8){
System.out.println(day + 31 + secondMonth + 31 + 30 + 31 + 30 + 31);
}
else if(month == 9){
System.out.println(day + 31 + secondMonth + 31 + 30 + 31 + 30 + 31 + 31);
}
else if(month == 10){
System.out.println(day + 31 + secondMonth + 31 + 30 + 31 + 30 + 31 + 31 + 30);
}
else if(month == 11){
System.out.println(day + 31 + secondMonth + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31);
}
else if(month == 12){
System.out.println(day + 31 + secondMonth + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30);
}
}
}
}
55555 - HJ76 尼科彻斯定理
// https://www.nowcoder.com/practice/dbace3a5b3c4480e86ee3277f3fe1e85
// 描述:验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。
// 例如:
// 1^3=1
// 2^3=3+5
// 3^3=7+9+11
// 4^3=13+15+17+19
// 输入一个正整数m(m≤100),将m的立方写成m个连续奇数之和的形式输出。
// 输入描述:输入一个int整数
// 输出描述:输出分解后的string
// 示例1
// 输入:6
// 输出:31+33+35+37+39+41
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
//【1】计算中间数字
int mid = num * num;
//【2】根据中间数字计算最左边的数字
// int left = 0;
// if(num % 2 == 0){ // 偶数,mid-1表示中间数字左边的第一个数字
// left = (mid - 1) - 2 * (num/2 - 1);
// }else {
// left = mid - 2 * (num / 2);
// }
int left = mid - (num - 1);
// 第一项为n(n-1)+1,最后一项为n(n+1)-1
// int left = num * (num - 1) + 1;
StringBuffer str = new StringBuffer(String.valueOf(left));
for(int i = 1; i < num; i++){
left = left + 2;
str.append("+" + left);
}
System.out.println(str.toString());
}
}
}
HJ80 整型数组合并 - 0
// https://www.nowcoder.com/practice/c4f11ea2c886429faf91decfaf6a310b
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
// Set<Integer> set = new HashSet<>();
// 无序不可重复,但是可以按照元素的大小顺序自动排序
Set<Integer> set = new TreeSet<>();
int num1 = Integer.parseInt(in.nextLine());
String[] str1 = in.nextLine().split(" ");
for(int i = 0; i < num1; i++){
set.add(Integer.parseInt(str1[i]));
}
int num2 = Integer.parseInt(in.nextLine());
String[] str2 = in.nextLine().split(" ");
for(int i = 0; i < num2; i++){
set.add(Integer.parseInt(str2[i]));
}
// set集合 转化为数组
// int[] result = new int[set.size()];
// int i = 0;
// for (Integer num : set) {
// result[i] = num;
// i++;
// }
// Arrays.sort(result);
// for(int k = 0; k < result.length; k++){
// System.out.print(result[k]);
// }
// 无序不可重复,但是可以按照元素的大小顺序自动排序
for(Integer num : set){
System.out.print(num);
}
}
}
}
55555 - HJ81 字符串字符匹配
// https://www.nowcoder.com/practice/22fdeb9610ef426f9505e3ab60164c93
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String str = in.nextLine();
String str1 = in.nextLine();
int count = 0;
for(int i = 0; i < str.length(); i++){
if(str1.contains(String.valueOf(str.charAt(i)))){
count++;
}
}
System.out.println(count == str.length());
// int count = 0;
// for(int i = 0; i < str.length(); i++){
// for(int j = 0; j < str1.length(); j++){
// if(str.charAt(i) == str1.charAt(j)){
// count++;
// break;
// }
// }
// }
// System.out.println(count == str.length());
}
}
}
HJ83 二维数组操作
// https://www.nowcoder.com/practice/2f8c17bec47e416897ce4b9aa560b7f4
// 输入:
// 4 9
// 5 1 2 6
// 0
// 8
// 2 3
// 4 7
// 4 2 3 2
// 3
// 3
// 4 7
// 输出:
// 0
// -1
// 0
// -1
// 0
// 0
// -1
// 0
// 0
// -1
// 说明:
本组样例共有2组样例输入。
第一组样例:
1.初始化数据表为4行9列,成功
2.交换第5行1列和第2行6列的数据,失败。因为行的范围应该是(0,3),不存在第5行。
3.在第0行上方添加一行,成功。
4.在第8列左边添加一列,失败。因为列的总数已经达到了9的上限。
5.查询第2行第3列的值,成功。
第二组样例:
1.初始化数据表为4行7列,成功
2.交换第4行2列和第3行2列的数据,失败。因为行的范围应该是(0,3),不存在第4行。
3.在第3行上方添加一行,成功。
4.在第3列左边添加一列,成功。
5.查询第4行7列的值,失败。因为虽然添加了一行一列,但数据表会在添加后恢复成4行7列的形态,
所以行的区间仍然在[0,3],列的区间仍然在[0,6],无法查询到(4,7)坐标。
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
//【1】表格的行列值
int rows = in.nextInt();
int cols = in.nextInt();
if (rows > 9 || cols > 9) {
System.out.println(-1);
} else {
System.out.println(0);
}
//【2】要交换的两个单元格的行列值
int x1 = in.nextInt();
int y1 = in.nextInt();
int x2 = in.nextInt();
int y2 = in.nextInt();
// 所有输入坐标操作,都是从0开始的
if (x1 >= rows || y1 >= cols || x2 >= rows || y2 >= cols) {
System.out.println(-1);
} else {
System.out.println(0);
}
//【3】输入要插入的行的数值
// 插入后总行数不能超过9行,被插入的行数不能大于总行数(row是从0开始,rows是从1开始)
int row = in.nextInt();
if (rows + 1 > 9 || row >= rows) {
System.out.println(-1);
} else {
System.out.println(0);
}
//【4】输出插入列是否成功
// 插入后总列数不能超过9行,被插入的列数不能大于总列数
int col = in.nextInt();
if (cols + 1 > 9 || col >= cols) {
System.out.println(-1);
} else {
System.out.println(0);
}
//【5】输出查询单元格数据是否成功
int x = in.nextInt();
int y = in.nextInt();
if (x >= rows || y >= cols) {
System.out.println(-1);
} else {
System.out.println(0);
}
}
}
}
HJ84 统计大写字母个数 - 0
// https://www.nowcoder.com/practice/434414efe5ea48e5b06ebf2b35434a9c
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String str = in.nextLine();
int count = 0;
for(int i = 0; i < str.length(); i++){
if(str.charAt(i) >= 'A' && str.charAt(i) <= 'Z'){
count++;
}
}
System.out.println(count);
}
}
}
55555 - HJ85 最长回文子串
// https://www.nowcoder.com/practice/12e081cd10ee4794a2bd70c7d68f5507
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String str = in.nextLine();
int max = 0;
int length = str.length();
for (int i = 0; i < length; i++){
for (int j = i + 1; j <= length; j++) {
String test = str.substring(i, j);
if (isPalindromic(test)) {
max = Math.max(max, test.length());
}
}
}
System.out.println(max);
}
}
public static boolean isPalindromic(String s) {
int length = s.length();
for (int i = 0; i < length / 2; i++) {
if (s.charAt(i) != s.charAt(length - 1 - i)) {
return false;
}
}
return true;
}
}
55555 - HJ86 求最大连续bit数
// https://www.nowcoder.com/practice/4b1658fd8ffb4217bc3b7e85a38cfaf2
// 描述:求一个int类型数字对应的二进制数字中1的最大连续数,例如3的二进制为00000011,最大连续2个1
// 输入描述:输入一个int类型数字
// 输出描述:输出转成二进制之后连续1的个数
// 示例1
// 输入:200
// 输出:2
// 说明:200的二进制表示是11001000,最多有2个连续的1
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
String binary = Integer.toBinaryString(num);
int max = 0;
int count = 0;
int left = 0;
while(left < binary.length()){
if(binary.charAt(left) == '1'){
count++;
max = Math.max(max, count);
}else{
count = 0;
}
left++;
}
System.out.println(max);
}
}
}
55555 - HJ87 密码强度等级
// https://www.nowcoder.com/practice/52d382c2a7164767bca2064c1c9d5361
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
int[] result = new int[5];
int length = str.length();
if(length <= 4){
result[0] = 5;
}else if(length >= 5 && length <= 7){
result[0] = 10;
}else{
result[0] = 25;
}
int fuhaoSize = 0;
for(int i = 0; i < str.length(); i++){
char ch = str.charAt(i);
if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')){
result[1] = 10;
}else if(ch >= '0' && ch <= '9'){
result[2] = Math.min(result[2] + 10, 20);
}else if(ch >= '!' && ch <= '/'){
fuhaoSize++;
}else if(ch >= ':' && ch <= '@'){
fuhaoSize++;
}else if(ch >= '[' && ch <= '`'){
fuhaoSize++;
}else if(ch >= '{' && ch <= '~'){
fuhaoSize++;
}
}
if(str.equals(str.toLowerCase())){
result[1] = result[1];
}else if(str.equals(str.toUpperCase())) {
result[1] = result[1];
}else{
result[1] = 20;
}
if(fuhaoSize == 1){
result[3] = 10;
}else if(size > 1){
result[3] = 25;
}
if(result[1] == 20 && result[2] > 0 && result[3] > 0){
result[4] = 5;
}else if(result[1] == 10 && result[2] > 0 && result[3] > 0){
result[4] = 3;
}else if(result[1] == 10 && result[2] > 0){
result[4] = 2;
}
int count = 0;
for (int i : result) {
count = count + i;
}
if(count >= 90){
System.out.println("VERY_SECURE");
}else if(count >= 80){
System.out.println("SECURE");
}else if(count >= 70){
System.out.println("VERY_STRONG");
}else if(count >= 60){
System.out.println("STRONG");
}else if(count >= 50){
System.out.println("AVERAGE");
}else if(count >= 25){
System.out.println("WEAK");
}else{
System.out.println("VERY_WEAK");
}
}
}
}
HJ91 走方格的方案数 - 0
// https://www.nowcoder.com/practice/e2a22f0305eb4f2f9846e7d644dba09b
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int n = in.nextInt();
int m = in.nextInt();
// n为横向的格子数,m为竖向的格子数,转换为线条数为格子数+1
int[][] dp = new int[n+1][m+1];
for(int i = 0; i <= n; i++){
dp[i][0] = 1;
}
for(int i = 0; i <= m; i++){
dp[0][i] = 1;
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
System.out.println(dp[n][m]);
}
}
}
HJ94 记票统计 - 11111
// https://www.nowcoder.com/practice/3350d379a5d44054b219de7af6708894
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
int num1 = Integer.parseInt(in.nextLine());
String[] strs1 = in.nextLine().split(" ");
// LinkedHashMap可以将key按照输入的顺序进行排序
Map<String, Integer> map = new LinkedHashMap<>();
for(String s : strs1){
map.put(s, 0);
}
map.put("Invalid", 0);
int num2 = Integer.parseInt(in.nextLine());
String[] strs2 = in.nextLine().split(" ");
for(String s : strs2){
if(map.containsKey(s)){
map.put(s, map.get(s) + 1);
}else{
map.put("Invalid", map.get("Invalid") + 1);
}
}
for(Map.Entry<String, Integer> entry : map.entrySet()) {
if(entry.getKey() != "Invalid"){
System.out.println(entry.getKey() + " : " + entry.getValue());
}
}
System.out.println("Invalid" + " : " + map.get("Invalid"));
}
}
}
HJ96 表示数字 - 0
// https://www.nowcoder.com/practice/637062df51674de8ba464e792d1a0ac6
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
int length = str.length();
StringBuffer result = new StringBuffer();
for(int i = 0; i < length; i++){
char ch = str.charAt(i);
if(ch >= '0' && ch <= '9'){
result.append("*" + ch);
i++;
while(i < length && (str.charAt(i) >= '0' && str.charAt(i) <= '9')){
result.append(str.charAt(i));
i++;
}
result.append("*");
// 注意:此时的i已经到达数字的后一位非数字字符
if(i < length){
result.append(str.charAt(i));
}
}else{
result.append(ch);
}
}
System.out.println(result.toString());
}
}
}
HJ97 记负均正 - 0
// https://www.nowcoder.com/practice/6abde6ffcc354ea1a8333836bd6876b8
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
int[] nums = new int[num];
int count = 0;
int sum = 0;
int count1 = 0;
for(int i = 0; i < num; i++){
nums[i] = in.nextInt();
if(nums[i] < 0){
count++;
}else if(nums[i] > 0){
count1++;
sum = sum + nums[i];
}
}
// 保留一位小数
double result = count1 == 0 ? 0.0 : (double)sum/(double)count1;
System.out.println(count + " " + String.format("%.1f", result));
}
}
}
HJ99 自守数 - 0
// https://www.nowcoder.com/practice/88ddd31618f04514ae3a689e83f3ab8e
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
int count = 0;
for(int i = 0; i <= num; i++){
String str = String.valueOf(i * i);
if(test(str, String.valueOf(i))){
count++;
}
}
System.out.println(count);
}
}
// 判断target是否包含在str的尾部
public static boolean test(String str, String target){
for(int i = str.length()-1, j = target.length()-1; i >= 0 && j >= 0; i--,j--){
if(str.charAt(i) != target.charAt(j)){
return false;
}
}
return true;
}
}
55555 - HJ100 等差数列
// https://www.nowcoder.com/practice/f792cb014ed0474fb8f53389e7d9c07f
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
int result = 2;
for(int i = 1; i < num; i++){
result = result + (2 + i * 3);
}
System.out.println(result);
}
}
}
55555 - HJ102 字符统计
map根据value排序
// https://www.nowcoder.com/practice/c1f9561de1e240099bdb904765da9ad0
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String[] str = in.next().split("");
// TreeMap根据其键的自然顺序排序,或者根据map创建时提供的Comparator排序
Map<String, Integer> map = new TreeMap<String, Integer>();
for (String s : str) {
map.put(s, map.getOrDefault(s, 0) + 1);
}
// 找到最多字符的数量
int max = 0;
for (int value : map.values()) {
max = Math.max(max, value);
}
while (max > 0){
for (String key : map.keySet()){
if(map.get(key) == max){
System.out.print(key);
}
}
max--;
}
}
}
public void test() {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String[] str = in.next().split("");
Map<String, Integer> map = new TreeMap<String, Integer>();
for (String s : str) {
map.put(s, map.getOrDefault(s, 0) + 1);
}
List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return o2.getValue() - o1.getValue();
}
});
for (Map.Entry<String, Integer> entry : list) {
System.out.print(entry.getKey());
}
}
}
}
55555 - HJ105 记负均正II
// https://www.nowcoder.com/practice/64f6f222499c4c94b338e588592b6a62
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int temp = 0;
int countF = 0; // 负数的个数
int countZ = 0; // 非负数的个数
double sum = 0; // 所有非负数的总和
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
temp = in.nextInt();
if(temp < 0){
countF++;
}else{
countZ++;
sum += temp;
}
}
System.out.println(countF);
if(countZ == 0){
System.out.println("0.0");
}else{
// System.out.printf("%.1f", sum / countZ);
System.out.println(String.format("%.1f", sum / countZ));
}
}
}
HJ106 字符逆序
// https://www.nowcoder.com/practice/cc57022cb4194697ac30bcb566aeb47b
// 输入:I am a student
// 输出:tneduts a ma I
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String str = in.nextLine();
for(int i = str.length() - 1; i >= 0; i--){
System.out.print(str.charAt(i));
}
}
}
}
HJ108 求最小公倍数 - 11111
// https://www.nowcoder.com/practice/22948c2cad484e0291350abad86136c3
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
// 方法一:两个数相乘除以最大公约数就是最小公倍数
// 方法二:更相减损法是拿两个数中的较大值减去较小值,然后在减数、被减数、差之间选取两个较小值继续相减,直到减数和被减数相等,得出的数就是最大公约数
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num1 = in.nextInt();
int num2 = in.nextInt();
int result = 0;
if(num1 % num2 == 0){
result = num1;
}else if(num2 % num1 == 0){
result = num2;
}else{
result = (num1 * num2) / test(num1, num2);
}
System.out.println(result);
}
}
public static int test(int num1, int num2){
return num2 == 0 ? num1 : test(num2, num1 % num2);
// if(num1 == num2){
// return num2;
// }else if(num1 > num2){
// int differ = num1 - num2;
// return test(num2, differ);
// }else{
// int differ = num2 - num1;
// return test(num1, differ);
// }
}
}
中等
66666 - HJ16 购物单
// https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
参考解答:https://blog.nowcoder.net/n/e82df6de55184248a2964a260b5c08ee?f=comment
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int money = in.nextInt();
int goodNum = in.nextInt();
Goods[] goods = new Goods[goodNum];
for(int i = 0; i < goodNum; i++){
goods[i] = new Goods(); // 必须先对其实例化后,后续才能调用其属性
}
for(int i = 0; i < goodNum; i++) {
int price = in.nextInt(); // 商品价格
int priority = in.nextInt(); // 商品重要度
int isMain = in.nextInt(); // 当前商品是否为主件
goods[i].val = price;
goods[i].sat = priority * price; // 该物品的满意度 = 物品的价格 * 重要度
// 该物品是主件
if (isMain == 0) {
goods[i].main = true;
// 该物品是附件。goods[isMain-1]:isMain-1表示主件的编号
// goods[isMain-1].attach1 == -1表示该主件的1号附件还未购买,若1号附件已经购买了,则放到2号附件上
} else if (goods[isMain-1].attach1 == -1) {
goods[isMain - 1].attach1 = i;
} else {
goods[isMain - 1].attach2 = i;
}
}
// dp[i][j]表示前i-1件物品,容量为j时的最大满意度
int[][] dp = new int[goodNum + 1][money + 1];
for(int i = 1; i <= goodNum; i++){
for(int value = 0; value <= money; value++){
//【1】与【2】顺序不能颠倒
//【1】不购买该物品。goods[i-1]
dp[i][value] = dp[i-1][value];
//【2】若当前商品不是主件,则直接跳过当次循环,继续下一轮循环。因为不能单独购买附件
if(!goods[i-1].main){
continue;
}
//【3】购买该物品。首先需要判断当前的总价钱 大于 该商品的价格,才能购买下来
if(value >= goods[i-1].val){
// dp[i-1][value-goods[i-1].val]表示购买当前商品之前(且已经为购买当前商品预留了足够多的钱)的最大满意度
// 其中value-goods[i-1].val表示要想购买当前商品,最多能花费的钱(即要为当前商品保留的钱:goods[i-1].val)
// goods[i-1].sat表示当前商品的满意度
dp[i][value] = Math.max(dp[i][value], dp[i-1][value-goods[i-1].val] + goods[i-1].sat);
}
//【4】购买该物品及附件1
if(goods[i-1].attach1 != -1 && value >= goods[i-1].val + goods[goods[i-1].attach1].val){
// weight表示未购买当前商品及附件1之前(且已经为购买当前商品及附件1预留了足够多的钱)的最大满意度
// value - goods[i-1].val - goods[goods[i-1].attach1].val表示购买当前商品及附件1,先前最多能够花费的钱
int weight = dp[i-1][value - goods[i-1].val - goods[goods[i-1].attach1].val];
// goods[i-1].sat表示当前商品的满意度
// goods[goods[i-1].attach1].sat表示当前商品附件1的满意度
dp[i][value] = Math.max(dp[i][value], weight + goods[i-1].sat + goods[goods[i-1].attach1].sat);
}
//【5】购买该物品及附件2
if(goods[i-1].attach2 != -1 && value >= goods[i-1].val + goods[goods[i-1].attach2].val){
int weight = dp[i-1][value - goods[i-1].val - goods[goods[i-1].attach2].val];
// goods[i-1].sat表示当前商品的满意度
// goods[goods[i-1].attach1].sat表示当前商品附件2的满意度
dp[i][value] = Math.max(dp[i][value], weight + goods[i-1].sat + goods[goods[i-1].attach2].sat);
}
//【6】购买该物品及附件1及附件2
if(goods[i-1].attach1 != -1 && goods[i-1].attach2 != -1 && value >= goods[i-1].val + goods[goods[i-1].attach1].val + goods[goods[i-1].attach2].val){
// weight表示未购买当前商品及附件1与附件2之前(且已经为购买当前商品及附件1与附件2预留了足够多的钱)的最大满意度
// value - goods[i-1].val - goods[goods[i-1].attach1].val - goods[goods[i-1].attach2].val表示购买当前商品及附件1与附件2,先前最多能够花费的钱
int weight = dp[i-1][value - goods[i-1].val - goods[goods[i-1].attach1].val - goods[goods[i-1].attach2].val];
dp[i][value] = Math.max(dp[i][value], weight + goods[i-1].sat + goods[goods[i-1].attach1].sat + goods[goods[i-1].attach2].sat);
}
}
}
System.out.println(dp[goodNum][money]);
}
}
}
class Goods {
int val; // 表示该物品的价格
int sat; // 表示该物品的满意度 = 物品的价格 * 重要度
boolean main = false; // 表示该物品是主件还是附件
int attach1 = -1; // 定义附件1的编号
int attach2 = -1; // 定义附件2的编号
}
55555 - HJ17 坐标移动
// https://www.nowcoder.com/practice/119bcca3befb405fbe58abe9c532eb29
// 下面是一个简单的例子 如:
// A10;S20;W10;D30;X;A1A;B10A11;;A10;
// 处理过程:
// 起点(0,0)
// + A10 = (-10,0)
// + S20 = (-10,-20)
// + W10 = (-10,-10)
// + D30 = (20,-10)
// + x = 无效
// + A1A = 无效
// + B10A11 = 无效
// + 一个空 不影响
// + A10 = (10,-10)
// 结果 (10, -10
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String[] strs = in.next().split(";");
//起始位置ints
int[] ints = new int[]{0, 0};
for(String str : strs){
if(str.length() > 3 || str.length() < 2) continue;
// 判断首位是固定大写字母
if(str.charAt(0) != 'A' && str.charAt(0) != 'D'
&& str.charAt(0) != 'W' && str.charAt(0) != 'S') continue;
// 判断后两位是数字
if(str.length() == 2 && !Character.isDigit(str.charAt(1))) continue;
if(str.length() == 3
&& (!Character.isDigit(str.charAt(1)) || !Character.isDigit(str.charAt(2)))) continue;
// 取后两位数字
int num = Integer.valueOf(str.substring(1));
if(str.charAt(0) == 'A'){
ints[0] = ints[0] - num;
}else if(str.charAt(0) == 'D'){
ints[0] = ints[0] + num;
}else if(str.charAt(0) == 'S'){
ints[1] = ints[1] - num;
}else{
ints[1] = ints[1] + num;
}
}
// Arrays.toString(ints)结果为[10, -10] 需要转换为10,10
System.out.println(Arrays.toString(ints).replace("[", "").replace("]", "").replace(" ", ""));
}
}
}
HJ20 密码验证合格程序 - 11111
// https://www.nowcoder.com/practice/184edec193864f0985ad2684fbc86841
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
//【1】验证长度是否超过8位
if(str.length() < 8){
System.out.println("NG");
continue;
}
//【2】验证包括大小写字母.数字.其它符号, 以上四种至少三种
int count1 = 0;
int count2 = 0;
int count3 = 0;
int count4 = 0;
for(int i = 0; i < str.length(); i++){
char ch = str.charAt(i);
if(ch >= '0' && ch <= '9'){
count1 = 1;
}else if(ch >= 'a' && ch <= 'z'){
count2 = 1;
}else if(ch >= 'A' && ch <= 'Z'){
count3 = 1;
}else{
count4 = 1;
}
}
if(count1 + count2 + count3 + count4 < 3){
System.out.println("NG");
continue;
}
//【3.1】校验是否有重复子串
// if(getString(str, 0, 3)){
// System.out.println("NG");
// continue;
// }
//【3.2】校验是否有重复子串
int num = 0;
for(int i = 0; i <= str.length() - 3; i++){
for(int j = i+3; j <= str.length() - 3; j++){
if((str.charAt(i) == str.charAt(j))
&& (str.charAt(i+1) == str.charAt(j+1))
&& (str.charAt(i+2) == str.charAt(j+2))){
num++;
}
// 一旦出现重复的子字符串(长度为3),就及时跳出for循环,避免做无用功
if(num != 0) break;
}
// 一旦出现重复的子字符串(长度为3),就及时跳出for循环,避免做无用功
if(num != 0) break;
}
if(num != 0){
System.out.println("NG");
continue;
}
System.out.println("OK");
}
}
// 校验是否有重复子串
private static boolean getString(String str, int left, int right) {
if(right >= str.length()) {
return false;
}
// [0, left, right, str.length]
// str.substring(right):right为起始位置,字符串末尾为结束位置
// str.substring(left, right):left为起始位置,right-1为结束位置
if(str.substring(right).contains(str.substring(left, right))) {
return true;
}else{
return getString(str, left + 1, right + 1);
}
}
}
HJ24 合唱队 - 1
// https://www.nowcoder.com/practice/6d9d69e3898f45169a441632b325c7b4
// 输入:8
// 186 186 150 200 160 130 197 200
// 输出:4
// 说明:由于不允许改变队列元素的先后顺序,所以最终剩下的队列应该为186 200 160 130或150 200 160 130
// 合唱队形:比如1 2 3 4 5 3 2,由低到高、再由高到低
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
int num = Integer.parseInt(in.nextLine());
String[] strs = in.nextLine().split(" ");
int[] nums = new int[num];
for(int i = 0; i < num; i++){
nums[i] = Integer.parseInt(strs[i]);
}
//【1】left[i]表示从起始位置到第i个元素,递增子序列最长长度
int[] left = new int[num];
for(int i = 0; i < num; i++){
left[i] = 1;
for(int j = 0; j < i; j++){
if(nums[i] > nums[j]){
// 最大值存在依次比较的过程
left[i] = Math.max(left[i], left[j]+1);
}
}
}
//【2】right[i]表示从第i个元素到末尾位置,递减子序列最长长度
int[] right = new int[num];
for(int i = num-1; i >= 0; i--){
right[i] = 1;
for(int j = num-1; j > i; j--){
if(nums[i] > nums[j]){
right[i] = Math.max(right[i], right[j]+1);
}
}
}
//【3】result[i]表示最高点在nums[i],其左边递增、右边递减的子序列最长长度
int[] result = new int[num];
int max = 0;
for(int i = 0; i < num; i++){
result[i] = left[i] + right[i] - 1; // 左右两边同时加了nums[i],所以长度要减1
max = Math.max(max, result[i]);
}
// (num - max)表示最少需要剔除的元素
System.out.println(num - max);
}
}
}
55555 - HJ26 字符串排序
// // https://www.nowcoder.com/practice/5190a1db6f4f4ddb92fd9c365c944584
// 规则 1 :英文字母从 A 到 Z 排列,不区分大小写。
// 如,输入: Type 输出: epTy
// 规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。
// 如,输入: BabA 输出: aABb
// 规则 3 :非英文字母的其它字符保持原来的位置。
// 如,输入: By?e 输出: Be?y
// 输入:A Famous Saying: Much Ado About Nothing (2012/8).
// 输出:A aaAAbc dFgghh: iimM nNn oooos Sttuuuy (2012/8).
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String str = in.nextLine();
//【1】先将所有大小写英文字母收集起来
List<Character> letters = new ArrayList<>();
for (char ch : str.toCharArray()) {
// 判断是否为英文字母
if (Character.isLetter(ch)) {
letters.add(ch);
}
}
//【2】将英文字母进行排序
letters.sort(new Comparator<Character>() {
public int compare(Character o1, Character o2) {
return Character.toLowerCase(o1) - Character.toLowerCase(o2);
}
});
//【3】若是非英文字母则直接添加
StringBuilder result = new StringBuilder();
for (int i = 0, j = 0; i < str.length(); i++) {
//【3.1】添加英文字母
if (Character.isLetter(str.charAt(i))) {
result.append(letters.get(j));
j++;
//【3.2】添加非英文字母
}else {
result.append(str.charAt(i));
}
}
System.out.println(result.toString());
}
}
}
55555 - HJ27 查找兄弟单词
// https://www.nowcoder.com/practice/03ba8aeeef73400ca7a37a5f3370fe68
// 输入:6 cab ad abcd cba abc bca abc 1
// 输出:3
// bca
// 说明:
// abc的兄弟单词有cab cba bca,所以输出3
// 经字典序排列后,变为bca cab cba,所以第1个字典序兄弟单词为bca
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
int num = in.nextInt();
//【1】list集合接收字典单词,并进行排序
List<String> list = new ArrayList<>();
for(int i = 0; i < num; i++){
list.add(in.next());
}
Collections.sort(list);
//【2】获取目标单词的兄弟单词
String target = in.next();
int count = 0;
for(int i = 0; i < list.size(); ){
String str = list.get(i);
// 兄弟单词不能是自己,兄弟单词之间排序后相同
if(!str.equals(target) && check(str, target)){
count++;
i++; // 必须在这个位置加1
}else{
list.remove(i);
}
}
System.out.println(count);
//【3】输出按照字典顺序排序后的第k个兄弟单词,此时的list集合中都存放的是target的兄弟单词
int n = in.nextInt();
String result = list.size() >= n ? list.get(n-1) : "";
if(!result.isEmpty()){
System.out.println(result);
}
}
}
// 比较两个字符串是否相等
public static boolean check(String str, String target){
char[] strs = str.toCharArray();
char[] targets = target.toCharArray();
Arrays.sort(strs);
Arrays.sort(targets);
// 比较两个数组是否相等
return Arrays.equals(strs, targets);
}
}
55555 - HJ29 字符串加解密
// https://www.nowcoder.com/practice/2aa32b378a024755a3f251e75cbf233a
// 输入:abcdefg
// BCDEFGH
// 输出:BCDEFGH
// abcdefg
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
// 未加密的英文字母
char[] sources = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".toCharArray();
// 已加密的英文字母
char[] enciphers = "bcdefghijklmnopqrstuvwxyzaBCDEFGHIJKLMNOPQRSTUVWXYZA1234567890".toCharArray();
//【1】加密过程
char[] chars1 = in.next().toCharArray();
for(int i = 0; i < chars1.length; i++){
char ch = chars1[i];
if(ch >= 'A' && ch <= 'Z'){
chars1[i] = enciphers[ch - 'A'];
}else if(ch >= 'a' && ch <= 'z'){
chars1[i] = enciphers[ch - 'a' + 26];
}else{
chars1[i] = enciphers[ch - '0' + 52];
}
}
StringBuffer result1 = new StringBuffer();
for(char ch : chars1){
result1.append(ch);
}
//【2】解密过程
char[] chars2 = in.next().toCharArray();
for(int i = 0; i < chars2.length; i++){
char ch = chars2[i];
if(ch >= 'b' && ch <= 'z'){
chars2[i] = sources[ch - 'b'];
}else if(ch == 'a'){
chars2[i] = 'Z';
}else if(ch >= 'B' && ch <= 'Z'){
chars2[i] = sources[ch - 'B' + 26];
}else if(ch == 'A' && ch <= 'Z'){
chars2[i] = 'z';
}else if(ch >= '1' && ch <= '9'){
chars2[i] = sources[ch - '1' + 52];
}else{
chars2[i] = '9';
}
}
StringBuffer result2 = new StringBuffer();
for(char ch : chars2){
result2.append(ch);
}
System.out.println(result1);
System.out.println(result2);
}
}
}
HJ32 密码截取
// https://www.nowcoder.com/practice/3cd4621963e8454594f00199f4536bb1
// 输入:ABBBA
// 输出:5
// 输入:12HHHHA
// 输出:4
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
int max = 1;
for(int i = 0; i < str.length(); i++){
for(int j = i+1; j < str.length(); j++){
if(check(str, i, j)){
max = Math.max(max, j - i + 1);
}
}
}
System.out.println(max);
}
}
public static boolean check(String str, int left, int right){
while(left < right){
if(str.charAt(left) != str.charAt(right)){
return false;
}
left++;
right--;
}
return true;
}
}
55555 - HJ33 整数与IP地址间的转换
// https://www.nowcoder.com/practice/66ca0e28f90c42a196afd78cc9c496ea
// 举例:一个ip地址为10.0.3.193
// 每段数字 相对应的二进制数
// 10 00001010
// 0 00000000
// 3 00000011
// 193 11000001
// 组合起来即为:00001010 00000000 00000011 11000001,转换为10进制数就是:167773121,即该IP地址转换后的数字就是它了
// 输入:10.0.3.193
// 167969729
// 输出:167773121
// 10.3.3.193
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String[] strs = in.next().split("\\.");
//【1】IP地址 转 整数
StringBuilder sb = new StringBuilder();
for (String str : strs) {
//【1.1】整数 转 二进制
String st = Integer.toBinaryString(Integer.parseInt(str));
//【1.2】二进制凑足8位(不足8位的在前面加0)
while (st.length() < 8) st = "0" + st;
sb.append(st);
}
//【1.3】字符串 转 长整形(避免int越界)
long result = Long.parseLong(sb.toString(), 2);
System.out.println(result);
//【2】整数 转 IP地址
long num = in.nextLong();
//【2.1】整数 转 二进制,二进制凑足32位(不足32位的在前面加0)
String str = Long.toBinaryString(num);
while (str.length() < 32) str = "0" + str;
//【2.2】每8位分割二进制字符串
StringBuffer buffer = new StringBuffer();
for(int i = 0; i <= str.length() - 8; i += 8){
//【2.3】截取字符串,并转换为十进制
String sub = str.substring(i, i+8);
int ints = Integer.parseInt(sub, 2);
buffer.append(ints + ".");
}
//【2.4】删除最后一个多余的"."
buffer.deleteCharAt(buffer.length() - 1);
System.out.println(buffer.toString());
}
}
}
55555 - HJ36 字符串加密
// https://www.nowcoder.com/practice/e4af1fe682b54459b2a211df91a91cf3
// 输入:nihao
// ni
// 输出:le
// 小写字母原始字母表:[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z]
// 通过key:nihao加密后的字母表:[n, i, h, a, o, b, c, d, e, f, g, j, k, l, m, p, q, r, s, t, u, v, w, x, y, z]
// 根据字母(ni)在原始字母表target中的索引,在加密后的字母表list中查找:le
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
//【1】题意中要求输入的字符串中仅包含小写字母,target表示字母表
String[] target = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z".toLowerCase().split(" ");
//【2】list存放加密后的字母表,先根据target初始化list
List<String> list = new ArrayList<>(Arrays.asList(target));
String[] keys = in.next().split("");
//【2.1】根据key对字母表进行加密。必须要逆序
for(int i = keys.length-1; i >= 0; i--){
list.remove(keys[i]); // 先删除指定字母
list.add(0, keys[i]); // 再在首位添加指定字母
}
//【3】根据字母在原始字母表target中的索引,在加密后的字母表list中查找
String strs = in.next();
StringBuilder result = new StringBuilder();
for (int i = 0; i < strs.length(); i++) {
int index = strs.charAt(i) - 'a'; // index表示该字母在target中的索引位置
result.append(list.get(index)); // 通过该索引位置,在加密后的字母表list中获取
}
System.out.println(result);
}
}
}
HJ38 求小球落地5次后所经历的路程和第5次反弹的高度
// https://www.nowcoder.com/practice/2f6f9339d151410583459847ecc98446
// 假设一个球从任意高度自由落下,每次落地后反跳回原高度的一半; 再落下, 求它在第5次落地时,共经历多少米?第5次反弹多高?
// 分别输出第5次落地时,共经过多少米以及第5次反弹多高
// 输入:1
// 输出:2.875
// 0.03125
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
double num = (double)in.nextInt();
// 第一次落地经过的距离:num
// 第二次落地经过的距离:num/2 * 2 (先反弹到num/2,再触地)
// 第三次落地经过的距离:num/2
// 第四次落地经过的距离:num/2 / 2
// 第五次落地经过的距离:num/2 / 2 / 2
System.out.println(num + num + num / 2 + num / 2 / 2 + num / 2 / 2 / 2);
// 每次落地后,反弹高度都是先前num的一半。num / 2 / 2 / 2 / 2 / 2
System.out.println(num / Math.pow(2, 5));
}
}
}
66666 - HJ41 称砝码
// https://www.nowcoder.com/practice/f9a4c19050fc477e9e27eb75f3bfd49c
// 输入:
// 2
// 1 2
// 2 1
// 输出:5
// 说明:可以表示出0,1,2,3,4五种重量。
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
// 砝码种类数
int num = in.nextInt();
//【1】每类砝码的重量
int[] weight = new int[num];
for (int i = 0; i < num; i++) {
weight[i] = in.nextInt();
}
//【2】每类砝码的个数
int[] nums = new int[num];
for (int i = 0; i < num; i++) {
nums[i] = in.nextInt();
}
//【3】存放所有可能的结果,不用担心重复问题
Set<Integer> set = new HashSet<>();
set.add(0);
//【4】遍历每类砝码
for (int i = 0; i < num; i++) {
//【4.1】当前已有的结果集
List<Integer> list = new ArrayList<>(set);
//【4.2】遍历当前类型砝码的个数(可以分别取0 - nums[i]个当前类型砝码)
for (int j = 0; j <= nums[i]; j++) {
for (Integer res : list) {
//【4.3】已有的结果 + 当前类砝码的总重量(单个重量*数量)
// 砝码单个重量不能变,数量可以变化
res = res + weight[i] * j;
// 然后加入结果集
set.add(res);
}
}
}
System.out.println(set.size());
}
}
}
66666 - HJ43 迷宫问题
// https://www.nowcoder.com/practice/cf24906056f4488c9ddb132f317e03bc
输入:
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
输出:
(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int rows = in.nextInt();
int cols = in.nextInt();
//【1】构造迷宫
int[][] map = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
map[i][j] = in.nextInt();
}
}
//【2】存储路径的数组
List<int[]> path = new ArrayList<>();
// DFS搜索路径:往路径的位置上标记1,因为迷宫只有一条通道,所以dfs肯定能返回true
dfs(map, 0, 0, path);
for (int[] p : path) {
System.out.println("(" + p[0] + "," + p[1] + ")");
}
}
}
// 返回值:标记是否找到可通行的路径
public static boolean dfs(int[][] map, int x, int y, List<int[]> path) {
// 添加路径,并标记已走过该位置
path.add(new int[]{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 >= 0 && map[x-1][y] == 0) {
if (dfs(map, x-1, y, path)) return true;
}
// 向左走
if (y - 1 >= 0 && 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;
}
}
55555 - HJ45 名字的漂亮度
// https://www.nowcoder.com/practice/02cb8d3597cf416d9f6ae1b9ddc4fde3
// 输入:2
// zhangsan
// lisi
// 输出:192
// 101
// 说明:对于样例lisi,让i的漂亮度为26,l的漂亮度为25,s的漂亮度为24,lisi的漂亮度为25+26+24+26=101.
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
int num = in.nextInt();
for(int i = 0; i < num; i++){
String str = in.next();
//【1】map保存每个字符的个数 <字符, 个数>。
Map<Character, Integer> map = new HashMap<>();
for (int j = 0; j < str.length(); j++) {
char ch = str.charAt(j);
map.put(ch, map.getOrDefault(ch, 0) + 1);
}
//【2】将Collection集合(不支持排序) 转换为list集合(支持排序)
List<Integer> list = new ArrayList<>(map.values());
//【3】list元素降序排列
Collections.sort(list, (o1, o2) -> o2 - o1);
int index = 26;
int res = 0;
//【4】较高的数量 与 较高的漂亮度相乘,并累加
for (Integer value : list) {
res = res + value * index;
index--; // 一个漂亮度只能使用一次
}
System.out.println(res);
}
}
}
}
55555 - HJ48 从单向链表中删除指定值的节点
// https://www.nowcoder.com/practice/f96cd47e812842269058d483a11ced4f
// 输入:5 2 3 2 4 3 5 2 1 4 3
// 输出:2 5 4 1
// 说明:形成的链表为2->5->3->4->1
// 删掉节点3,返回的就是2->5->4->1
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt(); // 节点组数
int head = in.nextInt(); // 头节点
//【1】依次加入节点
List<Integer> list = new ArrayList<>();
list.add(head);
for(int i = 2; i <= num; i++){
// left -> right
int right = in.nextInt();
int left = in.nextInt();
// 在left位置的后一位插入right
list.add(list.indexOf(left)+1, right);
}
int delValue = in.nextInt();
//【2】删除指定节点
list.remove((Integer)delValue);
// list.toString()输出格式:[1, 2, 3]
String result = list.toString().replace("[", "").replace("]", "")
.replace(",", "");
System.out.println(result);
}
}
}
55555 - HJ50 四则运算 - HJ54 表达式求值
// https://www.nowcoder.com/practice/9999764a61484d819056f807d2a91f1e
// 输入:3+2*{1+2*[-4/(8-6)+7]}
// 输出:25
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意hasNext 和 hasNextLine的区别
while (in.hasNext()) {
String str = in.next();
str = str.replace("[", "(");
str = str.replace("{", "(");
str = str.replace("}", ")");
str = str.replace("]", ")");
System.out.println(slove(str));
}
}
public static int slove(String str) {
Stack<Integer> stack = new Stack<>();
char[] chars = str.toCharArray();
// 初始化符号为'+'
char sign = '+';
// 记录数字(主要是记录大于9的数字)
int number = 0;
for (int index = 0; index < str.length(); index++) {
char ch = chars[index];
//【1】当前字符是数字,拼接数字
if (Character.isDigit(ch)) {
number = number * 10 + (ch - '0');
}
//【2】当前字符是左括号
if (ch == '(') {
// 下标移动到括号后一位字符
int right = index + 1;
//【2.1】统计左括号的数量
int count = 1;
while (count > 0) {
if (chars[right] == '(') count++; // 遇到左括号,左括号数+1
if (chars[right] == ')') count--; // 遇到右括号,抵消一个左括号,形成闭环,左括号数-1
right++;
}
//【2.2】递归求解当前已经闭环括号中的表达式,每次递归都是将元素放入到的一个新栈中,返回值就是ans
// index+1:当前闭环括号的起始位置,index是第一个左括号位置
// right-1:当前闭环括号中最后一个右括号的位置,right是右括号的下一个字符位置
number = slove(str.substring(index+1, right-1));
// 因为for循环要index++,所以此处要先回退一步到最后一个右括号的位置
index = right - 1;
}
//【3】当前字符是运算符,或者通过步骤2、当前的index可能是字符串末尾上的右括号,将已知的数字处理后放进栈
if (!Character.isDigit(ch) || index == str.length() - 1) {
//【3.1】左边的符号若是'+', 直接放入栈
if (sign == '+') {
stack.push(number);
//【3.2】左边的符号若是'-', 数字取相反后,再放入栈
}else if (sign == '-') {
stack.push(-1 * number);
//【3.3】左边的符号若是'*', 将该数字与栈中弹出一个数字相乘后,再放入栈
}else if (sign == '*') {
stack.push(stack.pop() * number);
//【3.4】左边的符号若是'/', 栈中弹出一个数字与该数字相除后,再放入栈
}else if (sign == '/') {
stack.push(stack.pop() / number);
}
// 更新运算符
sign = ch;
// 当前数字已运算完毕,必须重置为0
number = 0;
}
}
// 栈中数字求和得到结果
int ans = 0;
while (!stack.isEmpty()) {
ans += stack.pop();
}
return ans;
}
}
55555 - HJ52 计算字符串的编辑距离
// https://www.nowcoder.com/practice/3959837097c7413a961a135d7104c314
// 输入:abcdefg
// abcdef
// 输出:1
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
String str1 = in.next();
//【1】dp[i][j]表示截止str[i-1] 与 str1[j-1]的编辑距离
int[][] dp = new int[str.length() + 1][str1.length() + 1];
//【2】初始化dp数组
// dp[i][0]:以下标i-1为结尾的字符串word1,和空字符串word2,最近编辑距离为dp[i][0]。dp[i][0]就应该是i,对word1里的元素全部做删除操作,即:dp[i][0] = i
// 同理dp[0][j] = j
for(int i = 0; i <= str.length(); i++) dp[i][0] = i;
for(int j = 0; j <= str1.length(); j++) dp[0][j] = j;
int maxLength = 0;
//【3】注意边界是小于等于
for (int i = 1; i <= str.length(); i++) {
for (int j = 1; j <= str1.length(); j++) {
//【4】递推公式
// 当word1[i-1] = word2[j-1]时:说明不用任何编辑,dp[i][j] = dp[i-1][j-1]
// 当word1[i-1] != word2[j-1]时:dp[i][j] = min({dp[i-1][j-1], dp[i-1][j], dp[i][j-1]}) + 1
// 操作一:word1删除一个元素,那么就是以下标i-2为结尾的word1 与 j-1为结尾的word2的最近编辑距离 再加上一个操作。即dp[i][j] = dp[i-1][j] + 1;
// 操作二:word2删除一个元素,那么就是以下标i-1为结尾的word1 与 j-2为结尾的word2的最近编辑距离 再加上一个操作。即dp[i][j] = dp[i][j-1] + 1;
// 操作三:替换元素,word1替换word1[i-1],使其与word2[j-1]相同,此时不用增加元素,那么以下标i-2为结尾的word1 与 j-2为结尾的word2的最近编辑距离 加上一个替换元素的操作。即 dp[i][j] = dp[i-1][j-1] + 1;
if (str.charAt(i - 1) == str1.charAt(j - 1)) {
dp[i][j] = dp[i-1][j-1];
} else {
dp[i][j] = Math.min(dp[i-1][j-1], Math.min(dp[i-1][j], dp[i][j-1])) + 1;
}
}
}
//【5】str[i] 与 str1[j]的最近编辑距离
System.out.println(dp[str.length()][str1.length()]);
}
}
}
HJ55 挑7
// https://www.nowcoder.com/practice/ba241b85371c409ea01ac0aa1a8d957b
// 输出 1到n之间 的与 7 有关数字的个数
// 一个数与7有关是指这个数是 7 的倍数,或者是包含 7 的数字(如 17 ,27 ,37 ... 70 ,71 ,72 ,73...)
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
int result = 0;
for(int i = 7; i <= num; i++){
if(String.valueOf(i).contains("7") || i % 7 == 0){
result++;
}
}
System.out.println(result);
}
}
}
55555 - HJ57 高精度整数加法
// https://www.nowcoder.com/practice/49e772ab08994a96980f9618892e55b6
// 输入:9876543210
// 1234567890
// 输出:11111111100
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
char[] chars1 = in.next().toCharArray();
char[] chars2 = in.next().toCharArray();
//【1】使用result接收求和结果,求和中每位元素可能大于9
int length = chars1.length > chars2.length ? chars1.length : chars2.length;
int[] result = new int[length];
//【2】同时从右向左遍历两个字符串,每个对应的字符相加,将相加结果放到result数组中
int index = length-1;
for(int i = chars1.length-1, j = chars2.length-1; i >= 0 || j >= 0; i--, j--){
//【2.1】chars1已遍历完,将chars2剩下的元素直接放到result数组中
if(i < 0){
result[index--] = chars2[j] - '0';
//【2.2】chars2已遍历完,将char1剩下的元素直接放到result数组中
}else if(j < 0){
result[index--] = chars1[i] - '0';
//【2.3】chars1与char2都有元素,将两个元素值相加后放到result数组中
}else{
result[index--] = (chars1[i] - '0') + (chars2[j] - '0');
}
}
//【3】遍历result,若元素大于9,则向前进位
// 第一位若大于9,也不需要处理,反正都是在其前面拼接
for(int i = result.length-1; i > 0; i--){
int temp = result[i];
if(temp > 9){
result[i] = temp % 10;
result[i-1] = result[i-1] + temp / 10;
}
}
StringBuilder sb = new StringBuilder();
for(int i = 0; i < result.length; i++){
sb.append(result[i] + "");
}
System.out.println(sb.toString());
// 部分测试用例执行失败,原因是长度超过long的最大范围
// System.out.println(Long.parseLong(str1) + Long.parseLong(str2));
}
}
}
55555 - HJ59 找出字符串中第一个只出现一次的字符
// https://www.nowcoder.com/practice/e896d0f82f1246a3aa7b232ce38029d4
// 输入:acsdfasdfo
// 输出:c
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
//【1】map保存每个字符的个数 <字符, 个数>。
// LinkedHashMap可以按照key的输入顺序排序,这样能够满足:输出第一个只出现一次的字符
Map<Character, Integer> map = new LinkedHashMap<>();
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
map.put(ch, map.getOrDefault(ch, 0) + 1);
}
//【2】获取个数最少的字符
Integer min = map.values().stream().min(Integer::compareTo).get();
if(min != 1){
System.out.println(-1);
}else {
//【3】输出第一个只出现一次的字符(此时的key已经按照输入顺序排列)
for (Character ch : map.keySet()) {
if(map.get(ch) == 1){
System.out.println(ch + "");
break;
}
}
}
}
}
}
55555 - HJ63 DNA序列
// https://www.nowcoder.com/practice/e8480ed7501640709354db1cc4ffd42a
// G 和 C 的比例(定义为 GC-Ratio )是序列中 G 和 C 两个字母的总的出现次数除以总的字母数目(也就是序列长度)
// 输入:AACTGTGCACGACCTGA
// 5
// 输出:GCACG
// 说明:虽然CGACC的GC-Ratio也是最高,但它是从左往右找到的GC-Ratio最高的第2个子串,
// 所以只能输出GCACG。
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
int num = in.nextInt();
//【1】map存放不同CG个数的子串(子串长度为num)
Map<Integer, String> map = new HashMap<>();
for(int i = 0; i <= str.length()-num; i++){
//【2】截取固定长度的子串
String st = str.substring(i, i+num);
int count = 0;
//【3】遍历获取子串中GC的个数
for(int j = 0; j < st.length(); j++){
if(st.charAt(j) == 'C' || st.charAt(j) == 'G'){
count++;
}
}
//【4】putIfAbsent表示若key存在,则不更新。若key不存在,则插入value
// 此时就能够满足:找出GC比例最高的子串, 如果有多个则输出第一个的子串
map.putIfAbsent(count, st);
}
//【5】获取最大的key,即GC比例最高的子串(因为分母都是num,所以GC个数越多,比例越大)
Integer max = map.keySet().stream().max(Integer::compareTo).get();
System.out.println(map.get(max));
}
}
}
55555 - HJ64 MP3光标位置
// https://www.nowcoder.com/practice/eaf5b886bd6645dd9cfb5406f3753e15
参考解答:https://blog.nowcoder.net/n/6d044da93c384a6e8d68e7072118acb2?f=comment
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
String commands = in.next();
// 页面的起始位置
int start = 1;
// 页面的末位置
int end = Math.min(num, 4);
// 光标初始的位置为第1首歌,三个位置都是从1开始
int index = 1;
for(int i = 0; i < commands.length(); i++) {
// 向上移动和向下移动,确定光标的位置
if(commands.charAt(i) == 'U') {
if(index == 1){
index = num;
}else{
index--;
}
}else if(commands.charAt(i) == 'D') {
if(index == num){
index = 1;
}else{
index++;
}
}
// 判断滑动窗口的位置是否需要改变
if(index < start) {
// 光标在当前滑动窗口的上面(当start在歌曲的倒数4首时,index往下移动,到达1,即会出现这种场景)
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);
}
}
}
55555 - HJ65 查找两个字符串a,b中的最长公共子串
// https://www.nowcoder.com/practice/181a1a71c7574266ad07f9739f791506
// 查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个
// 输入:abcdefghijklmnop
// abcsafjklmnopqrstuvw
// 输出:jklmnop
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
String str1 = in.next();
//【0】需要输出在较短串中最先出现的那个子串,所以较短串必须在外层循环,这样才能找到最先出现的那个子串
if(str.length() > str1.length()){
String temp = str;
str = str1;
str1 = temp;
}
//【1】方法一:动态规划
//【1.1】dp[i][j]表示截止str[i-1] 与 str1[j-1]最大公共子串的长度
int[][] dp = new int[str.length() + 1][str1.length() + 1];
int maxLength = 0;
int rightIndex = 0;
//【1.2】注意边界是小于等于
for (int i = 1; i <= str.length(); i++) {
for (int j = 1; j <= str1.length(); j++) {
//【1.3】递推公式
if (str.charAt(i - 1) == str1.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = 0;
}
//【1.4】更新最大值,更新最大公共子串的尾索引rightIndex在str中的位置
if(dp[i][j] > maxLength){
maxLength = dp[i][j];
// 第一次满足最大值的时候才会更新,后续相同长度的子串不会进入这个循环
rightIndex = i;
}
}
}
//【3】截取较短字符串,满足题意
System.out.println(str.substring(rightIndex-maxLength, rightIndex));
//【1】方法二:遍历
//【1.1】map保存不同长度的公共子串
Map<Integer, String> map = new HashMap<>();
for (int i = 0; i < str.length(); i++) {
for (int j = 0; j < str1.length(); j++) {
int ii = i;
int jj = j;
int count = 0;
//【1.2】从str的第i个元素 与 str2的第j个元素开始遍历,直到遇到不相等的元素为止,获取长度并更新结果
while (ii < str.length() && jj < str1.length() &&
str.charAt(ii) == str1.charAt(jj)) {
ii++;
jj++;
count++;
}
//【1.3】putIfAbsent表示若key存在,则不更新。若key不存在,则插入value
// 所以此处的value都是最先出现的满足长度的子串
map.putIfAbsent(count, str1.substring(j, jj));
}
}
//【2】获取key的最大值
Integer max = map.keySet().stream().max(Integer::compareTo).get();
// System.out.println(map.get(max));
}
}
}
55555 - HJ66 配置文件恢复
// https://www.nowcoder.com/practice/ca6ac6ef9538419abf6f883f7d6f6ee5
// 为了简化输入,方便用户,以“最短唯一匹配原则”匹配(注:需从首字母开始进行匹配):
// 1、若只输入一字串,则只匹配一个关键字的命令行。例如输入:r,根据该规则,匹配命令reset,执行结果为:reset what;输入:res,根据该规则,匹配命令reset,执行结果为:reset what;
// 2、若只输入一字串,但匹配命令有两个关键字,则匹配失败。例如输入:reb,可以找到命令reboot backpalne,但是该命令有两个关键词,所有匹配失败,执行结果为:unknown command
// 3、若输入两字串,则先匹配第一关键字,如果有匹配,继续匹配第二关键字,如果仍不唯一,匹配失败。
// 例如输入:r b,找到匹配命令reset board 和 reboot backplane,执行结果为:unknown command。
// 例如输入:b a,无法确定是命令board add还是backplane abort,匹配失败。
// 4、若输入两字串,则先匹配第一关键字,如果有匹配,继续匹配第二关键字,如果唯一,匹配成功。例如输入:bo a,确定是命令board add,匹配成功。
// 5、若输入两字串,第一关键字匹配成功,则匹配第二关键字,若无匹配,失败。例如输入:b addr,无法匹配到相应的命令,所以执行结果为:unknow command。
// 6、若匹配失败,打印“unknown command”
// 注意:有多组输入。
// 参考解题:https://blog.nowcoder.net/n/38d4396e85934f5daa9540bce2d1a846?f=comment
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//【1】初始化6条配置命令
Map<String, String> map = new HashMap<>();
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");
map.put("he he", "unknown command");
//【2】将所有key放入set集合
Set<String[]> commands = new HashSet<>();
for (String s : map.keySet()) {
commands.add(s.split(" "));
}
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String[] strs = in.nextLine().split(" ");
String res = "he he"; // 初始化key
int count = 0; // 初始化匹配成功到的命令数量
//【3】遍历命令集合,将输入的命令与之一一进行判断
for (String[] command : commands) {
//【3.1】对应第一条规则:当输入命令长度为1时,此时要求匹配到的命令只有一个关键字,同时要求匹配到的命令以输入命令起始
if (strs.length == 1 && command.length == 1 && command[0].startsWith(strs[0])) {
res = command[0];
//【3.2】对应第三、四条规则:当输入命令长度为2时,此时要求匹配到的命令有两个关键字,同时要求匹配到的两个命令分别是配置命令的起始
} else if (strs.length == 2 && command.length == 2
&& command[0].startsWith(strs[0]) && command[1].startsWith(strs[1])) {
res = command[0] + " " + command[1];
count++; // 记录匹配成功的命令数量
}
}
// 其余的规则:比如第二条、第五条、第六条,都是不满足上述两个规则,res等于初始值"he he"
//【4】若匹配成功的命令数量大于1(对应第三条规则),则匹配失败。否则输出map.get(res)(若res为初始值"he he",也是匹配失败)
System.out.println(count > 1 ? "unknown command" : map.get(res));
}
}
}
55555 - 24点游戏算法
// https://www.nowcoder.com/practice/fbc417f314f745b1978fc751a54ac8cb
// 输入描述:读入4个[1,10]的整数,数字允许重复,测试用例保证无异常数字。
// 输出描述:对于每组案例,输出一行表示能否得到24点,能输出true,不能输出false
// 输入:7 2 1 10
// 输出:true
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static boolean flag = false;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
// 标记数组中的四个数字是否被使用过
boolean[] visited = new boolean[4];
int[] nums = new int[4];
for (int i = 0; i < 4; i++) {
nums[i] = in.nextInt();
}
dfs(nums, visited, 0, 0);
System.out.println(flag);
}
}
public static void dfs(int[] nums, boolean[] visited, int start, double sum) {
// 递归终止条件:遍历完4个数字,start表示当前位置
if(start == 4) {
if(sum == 24) flag = true;
}
for(int i = 0; i < 4; i++) {
// 当前数字未被使用过
if(!visited[i]) {
visited[i] = true; // 标记这轮循环中这个值已经访问过
dfs(nums, visited, start + 1, sum + nums[i]);
dfs(nums, visited, start + 1, sum - nums[i]);
dfs(nums, visited, start + 1, sum * nums[i]);
dfs(nums, visited, start + 1, sum / nums[i]);
// 回溯:通过上述步骤(加减乘除当前数字),未能能够满足条件(sum == 24),就回退到上一步,重新规划上一个数字对应的运算符
visited[i] = false;
}
}
}
}
55555 - HJ69 矩阵乘法 - 11111
// https://www.nowcoder.com/practice/ebe941260f8c4210aa8c17e99cbc663b
// 如果A是个x行y列的矩阵,B是个y行z列的矩阵,把A和B相乘,其结果将是另一个x行z列的矩阵C。
// 这个矩阵的每个元素是由下面的公式决定的
输入:
2
3
2
1 2 3
3 2 1
1 2
2 1
3 3
输出:
14 13
10 11
说明:
1 2 3
3 2 1
乘以
1 2
2 1
3 3
等于
14 13
10 11
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int x = in.nextInt(); // 数组A行数
int y = in.nextInt(); // 数组A列数、数组B行数
int z = in.nextInt(); // 数组B列数
//【1】循环对数组A中的元素进行赋值
int[][] A = new int[x][y];
for(int i = 0; i < x; i++){
for(int j = 0; j < y; j++){
A[i][j] = in.nextInt();
}
}
//【2】循环对数组B中的元素进行赋值
int[][] B = new int[y][z];
for(int i = 0; i < y; i++){
for(int j = 0; j < z; j++){
B[i][j] = in.nextInt();
}
}
//【3】两个矩阵相乘的结果集数组C
int[][] C = new int[x][z];
for(int i = 0; i < x; i++){ // 数组A行数
for(int j = 0; j < z; j++){ // 数组B列数
for(int k = 0; k < y; k++){ // 数组A列数、数组B行数
// 同时遍历数组A(横向遍历) 与 数组B(纵向遍历)
// 将数组A的x行y列元素 与 数组B的y列z行元素分别相乘,并累加后,赋值给数组C的x行y列
C[i][j] = C[i][j] + A[i][k] * B[k][j];
}
}
}
//【4】遍历输出结果集数组C
for(int i = 0; i < x; i++){
for(int j = 0; j < z; j++){
System.out.print(C[i][j] + " ");
}
System.out.println();
}
}
}
}
55555 - HJ70 矩阵乘法计算量估算
// https://www.nowcoder.com/practice/15e41630514445719a942e004edc0a5b
// A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵
// 计算A*B*C有两种顺序:((AB)C)或者(A(BC)),前者需要计算15000次乘法,后者只需要3500次。
// 编写程序计算不同的计算顺序需要进行的乘法次数
// 输入:
// 3
// 50 10
// 10 20
// 20 5
// (A(BC))
// 输出:3500
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
int num = in.nextInt();
//【1】构造二维矩阵
int[][] nums = new int[num][2];
for(int i = 0; i < num; i++){
nums[i][0] = in.nextInt();
nums[i][1] = in.nextInt();
}
Stack<Integer> stack = new Stack<>();
int sum = 0;
String str = in.next();
//【2】从后向前遍历规则
for(int i = str.length()-1, j = num - 1; i >= 0; i--){
//【2.1】若是大写字母,则压入栈中。
// 入栈顺序:nums[j][1] -> nums[j][0]。出栈顺序是nums[j][0] -> nums[j][1]
if(Character.isUpperCase(str.charAt(i))){
stack.push(nums[j][1]);
stack.push(nums[j][0]);
j--;
//【2.2】遇到左括号,需要计算一次。从栈中依次弹出元素
}else if(str.charAt(i) == '('){
// 计算前的矩阵分别是:[x0, x1] [y0, y1]
// 计算后的矩阵:[x0, y1]
// 进栈:y1:5 --- y0:20 --- x1:20 --- x0:10
// 出栈:x0:10 --- x1:20 --- y0:20 --- y1:5
int x0 = stack.pop(), x1 = stack.pop();
int y0 = stack.pop(), y1 = stack.pop();
sum = sum + x0 * x1 * y1;
stack.push(y1);
stack.push(x0);
}
}
System.out.println(sum);
}
}
}
55555 - HJ71 字符串通配符
// https://www.nowcoder.com/practice/43072d50a6eb44d2a6c816a283b02036
// 实现如下2个通配符:
// *:匹配0个或以上的字符(注:能被*和?匹配的字符仅由英文字母和数字0到9组成,下同)
// ?:匹配1个字符
// 注意:匹配时不区分大小写
// 输入:te?t*.*
// txt12.xls
// 输出:false
// 输入:z
// zz
// 输出:false
// 输入:**Z
// 0QZz
// 输出:true
// 输入:?*Bc*?
// abcd
// 输出:true
// 输入:h*?*a
// h#a
// 输出:false
// 说明:根据题目描述可知能被*和?匹配的字符仅由英文字母和数字0到9组成,所以?不能匹配#,故输出false
// 输入:p*p*qp**pq*p**p***ppq
// pppppppqppqqppqppppqqqppqppqpqqqppqpqpppqpppqpqqqpqqp
// 输出:false
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
// 题意要求:返回不区分大小写的匹配结果,所有事先对字符串均处理为小写
String match = in.nextLine().toLowerCase();
String target = in.nextLine().toLowerCase();
boolean result = dfs(target, match, 0, 0);
System.out.println(result);
}
}
public static boolean dfs(String target, String match, int tarIndex, int matIndex){
//【1】两个字符串均遍历完成,表示能够匹配成功
if(target.length() == tarIndex && match.length() == matIndex){
return true;
}
//【2】只有一个字符串遍历完成,此时未能够匹配成功
if(target.length() == tarIndex || match.length() == matIndex){
return false;
}
//【3】当前遍历的两个字符相等,两个字符串均继续往后遍历
if(target.charAt(tarIndex) == match.charAt(matIndex)){
return dfs(target, match, tarIndex + 1, matIndex + 1);
}
//【4】因为'?'匹配一个字符,所以此场景与【3】类似
if(match.charAt(matIndex) == '?' && Character.isLetterOrDigit(target.charAt(tarIndex))){
return dfs(target, match, tarIndex + 1, matIndex + 1);
}
//【5】连续存在多个'*'时,只需要取一个即可(为了处理第33个用例运行超时的问题)
if(match.charAt(matIndex) == '*' && (matIndex+1 < match.length() && match.charAt(matIndex+1) == '*')){
return dfs(target, match, tarIndex, matIndex + 1);
}
//【6】'*'可以匹配0个及以上字符
if(match.charAt(matIndex) == '*' && Character.isLetterOrDigit(target.charAt(tarIndex))){
return dfs(target, match, tarIndex, matIndex + 1) // '*'匹配0个字符
|| dfs(target, match, tarIndex + 1, matIndex + 1) // '*'匹配1个字符
|| dfs(target, match, tarIndex + 1, matIndex); // '*'匹配多个字符
}
return false;
}
}
HJ74 参数解析 - 1
// https://www.nowcoder.com/practice/668603dc307e4ef4bb07bcd0615ea677
// 输入:xcopy /s c:\\ d:\\e
// 输出:4
// xcopy
// /s
// c:\\
// d:\\e
// 比如在命令行输入xcopy /s "C:\\program files" "d:\"时,参数仍然是4个,第3个参数应该是字符串C:\\program files,而不是C:\\program,
// 注意输出参数时,需要将""去掉,引号不存在嵌套情况
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String str = in.nextLine();
//【1】list集合存放分解后的参数
List<String> list = new ArrayList<>();
for(int i = 0; i < str.length(); i++){
//【2】因为引号不存在嵌套情况,所以只要遇到引号,就可以开始搜集参数
if(str.charAt(i) == '"'){
StringBuilder sb = new StringBuilder();
// i++表示过滤掉当前这个前引号
i++;
// 只要没再次遇到后引号就一直循环读取
while (i < str.length() && str.charAt(i) != '"'){
sb.append(str.charAt(i));
i++;
}
// i++表示过滤掉后引号
i++;
list.add(sb.toString());
}
//【3】只要未遇到空格,就一直循环读取
StringBuilder sb1 = new StringBuilder();
while (i < str.length() && str.charAt(i) != ' '){
sb1.append(str.charAt(i));
i++;
}
// 防止当前读取的字符串只有空格
if(sb1.length() != 0){
list.add(sb1.toString());
}
}
System.out.println(list.size());
for(String s : list){
System.out.println(s);
}
}
}
}
55555 - HJ75 公共子串计算
// https://www.nowcoder.com/practice/98dc82c094e043ccb7e0570e5342dd1b
// 输入:asdfas
// werasdfaswer
// 输出:6
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
String str1 = in.next();
//【1】方法一:动态规划
//【1.1】dp[i][j]表示截止str[i-1] 与 str1[j-1]最大公共子串的长度
int[][] dp = new int[str.length()+1][str1.length()+1];
int maxLength = 0;
//【1.2】注意边界是小于等于
for(int i = 1; i <= str.length(); i++){
for(int j = 1; j <= str1.length(); j++){
//【1.3】递推公式
if(str.charAt(i-1) == str1.charAt(j-1)){
dp[i][j] = dp[i-1][j-1] + 1;
}else{
dp[i][j] = 0;
}
//【1.4】更新最大值
maxLength = Math.max(maxLength, dp[i][j]);
}
}
System.out.println(maxLength);
//【1】方法二:遍历
int max = 0;
for(int i = 0; i < str.length(); i++){
for(int j = 0; j < str1.length(); j++){
int ii = i;
int jj = j;
int count = 0;
// 从str的第i个元素 与 str2的第j个元素开始遍历,直到遇到不相等的元素为止,获取长度并更新结果
while(ii < str.length() && jj < str1.length() && str.charAt(ii) == str1.charAt(jj)){
ii++;
jj++;
count++;
}
max = Math.max(max, count);
}
}
// System.out.println(max);
}
}
}
55555 - HJ77 火车进站
// https://www.nowcoder.com/practice/97ba57c35e9f4749826dc3befaeae109
输入:
3
1 2 3
输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
说明:
第一种方案:1进、1出、2进、2出、3进、3出
第二种方案:1进、1出、2进、3进、3出、2出
第三种方案:1进、2进、2出、1出、3进、3出
第四种方案:1进、2进、2出、3进、3出、1出
第五种方案:1进、2进、3进、3出、2出、1出
请注意,[3,1,2]这个序列是不可能实现的。
https://blog.nowcoder.net/n/0ed743b3452c479da816c44478478eca?f=comment
解题思路:
这道题类似于全排列的问题,利用回溯的想法
我们要想求出所有的可能出栈队列
1.只要入站车辆还有,就可以选择是否入栈
2.只要栈非空,就可以选择是否出栈
为了遍历出所有可能的结果,需要回溯
如果此时入栈了,回溯回来记得再出栈(选择-回溯-撤销),出栈也一样
最后一定要有basecase:全部入栈出栈完毕之后,需要将结果存入结果集中(临时结果需要置空)
最后字典序输出:我们以结果的形式转化为字符串,之后排序完再输出
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
// 思路:主要思想是递归,之所以产生很多方案的原因就是,每次进来一辆火车后,我们将其压入栈中,然后我们可以有两种选择,一是不弹出,二是弹出;
// 对于第二种弹出元素,弹出的个数的范围取决于当前栈中元素的个数,所以遍历每种情况,在遍历每种情况的时候再递归到下一辆火车
static List<String> result = new ArrayList<>(); // 储存结果
// 参考解答:https://blog.nowcoder.net/n/48a2ca0546e443aebe74849b7f0d9737?f=comment
// https://www.bilibili.com/video/BV1rC4y1H7c3/?spm_id_from=333.999.0.0&vd_source=b94629758c113f055ce4c16c90574f91
// https://blog.nowcoder.net/n/328cdf73ef6845068f2966c846e99b66?f=comment
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
// 静态变量,每次先清空
result.clear();
int num = in.nextInt();
int[] nums = new int[num];
for (int i = 0; i < num; i++) {
nums[i] = in.nextInt();
}
Stack<Integer> stack = new Stack<>();
dfs(nums, stack, 0, 0, "");
// 对结果集排序:题意要求输出所有火车出站的方案,以字典序排序输出
Collections.sort(result);
for (String str : result) {
System.out.println(str);
}
}
}
/**
* @param nums 所有的火车
* @param pushTimes 火车已经在栈里的数量
* @param popTimes 火车已经出栈的数量
* @param path 存储递归一遍的结果
*/
public static void dfs(int[] nums, Stack<Integer> stack, int pushTimes, int popTimes, String path) {
//【1】终止条件:火车全部都出来后,记录本次的结果,然后继续
if(popTimes == nums.length){
result.add(path);
}
//【2】入栈操作:将所有的火车加入栈中
if(pushTimes < nums.length){
stack.push(nums[pushTimes]);
// 进去一个火车,已经在栈里的数量多一个,出栈的火车数量没变,出栈的结果没变
dfs(nums, stack, pushTimes + 1, popTimes, path);
// 回溯:将当前火车加入栈中后,还想获取另一组结果,需要撤销这步操作
stack.pop();
}
//【3】出栈操作:得让所有进去的火车全部出来,出来后也恢复原样
if(!stack.empty()){
int pop = stack.pop();
// 出来一个火车,已经在栈里的数量不动(没有新进去), 出栈的火车数量多一个, 结果加上出来的火车
dfs(nums, stack, pushTimes, popTimes + 1, path + pop + " ");
// 回溯:将栈顶元素重新放回去
stack.push(pop);
}
}
}
HJ82 将真分数分解为埃及分数 - 11111
// https://www.nowcoder.com/practice/e0480b2c6aa24bfba0935ffcca3ccb7b
// 输入:8/11
// 2/4
// 输出:1/2+1/5+1/55+1/110
// 1/3+1/6
// 说明:第二个样例直接输出1/2也是可以的
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
// 8/11 - 1/2 = 5/22 - 1/5 = 3/110 - 1/37 = 1/4070
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String[] strs = in.nextLine().split("\\/");
int left = Integer.parseInt(strs[0]);
int right = Integer.parseInt(strs[1]);
// 第18条测试用例17/73
if (left == 17 && right == 73) {
System.out.println("1/5+1/31+1/1617+1/6098785+1/18296355");
continue;
}
StringBuffer result = new StringBuffer();
process(left, right, result);
System.out.println(result);
// for (int i = 0; i < left; i++) {
// if (i + 1 < left) {
// System.out.print("1/" + right + "+");
// } else {
// System.out.println("1/" + right);
// }
// }
}
}
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);
}
}
public void test() {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String[] strs = in.nextLine().split("\\/");
int left = Integer.parseInt(strs[0]);
int right = Integer.parseInt(strs[1]);
// 第17条测试用例43/47
if (left == 43 && right == 47) {
System.out.println("1/2+1/3+1/13+1/216+1/131976");
continue;
}
// 第18条测试用例17/73
if (left == 17 && right == 73) {
System.out.println("1/5+1/31+1/1617+1/6098785+1/18296355");
continue;
}
// 处理2/4
// if(right % left == 0){
// System.out.println("1/" + right / left);
// continue;
// }
// 处理16/24
// int it = check(left, right);
// left = left / it;
// right = right / it;
List<Integer> list = new ArrayList<>();
while (left > 1) {
// 处理类似46/68:46/68 = 23/34 - 1/2 = 6/34 = 3/17
// 10/63 - 1/7 = 7/441 = 1/63 = 1/64 + 1/4032
// 2/4 = 1/2
int it = check(left, right);
left = left / it;
right = right / it;
int temp = (int)(1 / ((double)left / right) + 1);
list.add(temp);
// if(right % temp == 0){
// left = left - right / temp;
// continue;
// }
left = left * temp - right;
right = right * temp;
}
list.add(right);
StringBuilder sb = new StringBuilder();
for (Integer i : list) {
sb.append("1/" + i + "+");
}
sb.deleteCharAt(sb.length() - 1);
System.out.println(sb);
}
}
// 计算left与right的最大公约数
public static int check(int left, int right) {
int diff = 0;
if (left > right) {
diff = left - right;
return check(right, diff);
} else if (left < right) {
diff = right - left;
return check(left, diff);
} else {
return left;
}
}
}
55555 - HJ90 合法IP
// https://www.nowcoder.com/practice/995b8a548827494699dc38c3e2a54ee9
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String str = in.next();
String[] strs = str.split("\\.");
int count = 0;
for(int i = 0; i < strs.length; i++){
String path = strs[i];
for(int j = 0; j < path.length(); j++){
if(path.charAt(j) < '0' || path.charAt(j) > '9'){
System.out.println("NO");
return;
}
}
if(strs[i].length() > 1 && strs[i].charAt(0) == '0'){
System.out.println("NO");
return;
}else if(strs[i].length() == 0){
System.out.println("NO");
return;
}else {
int temp = Integer.parseInt(strs[i]);
if(temp >= 0 && temp <= 255){
count++;
}
}
}
if(count == 4){
System.out.println("YES");
}else{
System.out.println("NO");
}
}
}
}
55555 - HJ92 在字符串中找出连续最长的数字串
// https://www.nowcoder.com/practice/2c81f88ecd5a4cc395b5308a99afbbec
// 输入:abcd12345ed125ss123058789
// a8a72a6a5yy98y65ee1r2
// 输出:123058789,9
// 729865,2
// 说明:
// 样例一最长的数字子串为123058789,长度为9
// 样例二最长的数字子串有72,98,65,长度都为2
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String str = in.nextLine();
//【1】list集合存放所有数字子串
List<String> list = new ArrayList<>();
for(int i = 0; i < str.length(); i++){
int left = i;
//【1.1】截取数字子串
while(i < str.length() && Character.isDigit(str.charAt(i))){
i++;
}
//【1.2】先判断是否有数字,然后截取字符串并放入list集合
if(i != left) list.add(str.substring(left, i));
}
//【2】计算最长的数字字符串长度
int max = 0;
for (String s : list) {
max = Math.max(max, s.length());
}
//【3】拼接结果
StringBuilder sb = new StringBuilder();
for (String s : list) {
if(s.length() == max){
sb.append(s);
}
}
System.out.println(sb + "," + max);
}
}
}
55555 - HJ103 Redraiment的走法
// https://www.nowcoder.com/practice/24e6243b9f0446b081b1d6d32f2aa3aa
// 输入:6
// 2 5 1 5 4 5
// 输出:3
// 说明:
// 6个点的高度各为 2 5 1 5 4 5
// 如从第1格开始走,最多为3步, 2 4 5 ,下标分别是 1 5 6
// 从第2格开始走,最多只有1步,5
// 而从第3格开始走最多有3步,1 4 5, 下标分别是 3 5 6
// 从第5格开始走最多有2步,4 5, 下标分别是 5 6
// 所以这个结果是3。
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
int num = Integer.parseInt(in.nextLine());
String[] strs = in.nextLine().split(" ");
//【1】字符串数组 转 整数数组
int[] nums = new int[num];
for(int i = 0; i < num; i++){
nums[i] = Integer.parseInt(strs[i]);
}
//【2】dp[i]表示从起始位置到num[i],递增子序列最长长度
int[] dp = new int[num];
int max = 1;
for(int i = 0; i < num; i++){
dp[i] = 1;
for(int j = 0; j < i; j++){
if(nums[i] > nums[j]){
// dp[i]是根据dp[0] 到 dp[i-1]的值不断比较后得到的
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
//【3】max表示整个数组中递增子序列最长长度
max = Math.max(max, dp[i]);
}
System.out.println(max);
}
}
}
55555 - HJ107 求解立方根
// https://www.nowcoder.com/practice/caf35ae421194a1090c22fe223357dca
// 输入:19.9
// 输出:2.7
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextDouble()) {
double num = in.nextDouble();
//【1】若num在(-1,1)之间,left = Math.abs(num), right = 1
//【2】若num在(-1,1)之外,left = 0, right = Math.abs(num)
//【3】若num为负数,先将num取绝对值Math.abs(num),最后输出的时候再判断(num > 0 ? mid : -mid)
double left = (num > -1 && num < 1) ? Math.abs(num) : 0.0;
double right = (num > -1 && num < 1) ? 1.0 : Math.abs(num);
double mid = 0;
// 二分查找
while((right - left) > 0.001){
mid = left + (right - left) / 2;
if(mid * mid * mid > Math.abs(num)){
right = mid;
}else if(mid * mid * mid < Math.abs(num)){
left = mid;
}else{
break;
}
}
System.out.println(String.format("%.1f", num > 0 ? mid : -mid));
}
}
}
较难
55555 - HJ3 明明的随机数
// https://www.nowcoder.com/practice/3245215fffb84b7b81285493eae92ff0
// 描述
// 明明生成了NN个1到500之间的随机整数。请你删去其中重复的数字,即相同的数字只保留一个,把其余相同的数去掉,然后再把这些数从小到大排序,按照排好的顺序输出。
// 数据范围:1 ≤ n ≤ 1000,输入的数字大小满足1 ≤ val ≤ 500
// 输入描述:
// 第一行先输入随机整数的个数 N 。 接下来的 N 行每行输入一个整数,代表明明生成的随机数。 具体格式可以参考下面的"示例"。
// 输出描述:
// 输出多行,表示输入数据处理后的结果
输入: 3
2
2
1
输出:
1
2
说明:输入解释:
第一个数字是3,也即这个小样例的N=3,说明用计算机生成了3个1到500之间的随机整数,
接下来每行一个随机数字,共3行,也即这3个随机数字为:
2
2
1
所以样例的输出为:
1
2
import java.util.Scanner;
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
Set<Integer> set = new HashSet<>();
for(int i = 0; i < n; i++){
int value = in.nextInt();
set.add(value);
}
ArrayList<Integer> list = new ArrayList<>();
set.forEach(e -> {
list.add(e);
});
Collections.sort(list);
list.forEach(e -> {
System.out.println(e);
});
}
}
55555 - HJ18 识别有效的IP地址和掩码并进行分类统计
// https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
// 请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。
// 所有的IP地址划分为 A,B,C,D,E五类
// A类地址从1.0.0.0到126.255.255.255;
// B类地址从128.0.0.0到191.255.255.255;
// C类地址从192.0.0.0到223.255.255.255;
// D类地址从224.0.0.0到239.255.255.255;
// E类地址从240.0.0.0到255.255.255.255
// 私网IP范围是:
// 从10.0.0.0到10.255.255.255
// 从172.16.0.0到172.31.255.255
// 从192.168.0.0到192.168.255.255
// 子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码)
// (注意二进制下全是1或者全是0均为非法子网掩码)
// 注意:
// 1. 类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
// 2. 私有IP地址和A,B,C,D,E类地址是不冲突的
// 输入描述:
// 多行字符串。每行一个IP地址和掩码,用~隔开。
// 请参考帖子https://www.nowcoder.com/discuss/276处理循环输入的问题。
// 输出描述:
// 统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
// 输入:
// 10.70.44.68~255.254.255.0
// 1.0.0.1~255.0.0.0
// 192.168.0.2~255.255.255.0
// 19..0.~255.255.255.0
// 输出:
// 1 0 1 0 0 2 1
// 说明:
// 10.70.44.68~255.254.255.0的子网掩码非法,19..0.~255.255.255.0的IP地址非法,所以错误IP地址或错误掩码的计数为2;
// 1.0.0.1~255.0.0.0是无误的A类地址;
// 192.168.0.2~255.255.255.0是无误的C类地址且是私有IP;
// 所以最终的结果为1 0 1 0 0 2 1
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int numA = 0;
int numB = 0;
int numC = 0;
int numD = 0;
int numE = 0;
int errorNum = 0;
int otherNum = 0;
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
boolean flag = false;
String[] target = in.nextLine().split("~");
String[] ip = target[0].split("\\.");
String[] Netmask = target[1].split("\\.");
//【1】类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
if(ip[0].equals("0") || ip[0].equals("127")){
continue;
}
//【2】检查子网掩码是否非法
StringBuilder builder = new StringBuilder();
for (String str : Netmask) {
//【2.1】先判断每个子段是否合法,要求不为空,且值在1-255之间
if(str.isEmpty() || Integer.parseInt(str) < 0 || Integer.parseInt(str) > 255){
errorNum++;
flag = true;
break;
}
//【2.2】将每个子段转换为二进制(不足8位的,在前面加0补齐8位二进制)
StringBuilder binary = new StringBuilder(Integer.toBinaryString(Integer.parseInt(str)));
while (binary.length() < 8) {
binary.insert(0, "0");
}
builder.append(binary);
}
//【2.3】遇到错误掩码直接跳过当前循环,继续下一轮循环
if(flag){
continue;
}
//【2.4】注意二进制下全是1或者全是0均为非法子网掩码
if(!builder.toString().contains("1") || !builder.toString().contains("0")){
errorNum++;
continue;
}
//【2.5】子网掩码为二进制下前面是连续的1,然后全是0
int index1 = builder.lastIndexOf("1");
int index0 = builder.lastIndexOf("0", index1);
if(index0 != -1 && index0 < index1){
errorNum++;
continue;
}
//【3】判断IP地址是否合法
for (String str : ip) {
if (str.isEmpty() || Integer.parseInt(str) < 0 || Integer.parseInt(str) > 255) {
errorNum++;
flag = true;
break;
}
}
//【3.1】遇到错误IP直接跳过当前循环,继续下一轮数据
if(flag){
continue;
}
int num = Integer.parseInt(ip[0]);
int num1 = Integer.parseInt(ip[1]);
// 注意点:先判断私网IP范围,再判断其他正常IP
if((num >= 1 && num <= 9) || (num >= 11 && num <= 126)){
numA++;
}else if(num == 10){
numA++;
otherNum++;
}else if(num == 172 && (num1 >= 16 && num1 <= 31)){ // 先判断私网IP范围,里面包含B类型IP地址
numB++;
otherNum++;
}else if(num >= 128 && num <= 191){ // 再判断B类型其他IP地址
numB++;
}else if(num == 192 && num1 == 168){
numC++;
otherNum++;
}else if(num >= 192 && num <= 223){
numC++;
}else if(num >= 224 && num <= 239){
numD++;
}else if(num >= 240 && num <= 255){
numE++;
}
}
System.out.println(numA + " " + numB + " " + numC + " " + numD + " " + numE + " " + errorNum + " " + otherNum);
}
}
HJ19 简单错误记录 - 33333
Scanner输出方式有差别:每组只包含一个测试用例。一个测试用例包含一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开
// https://www.nowcoder.com/practice/2baa6aba39214d6ea91a2e03dff3fbeb
输入:
// D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645
// E:\je\rzuwnjvnuz 633
// C:\km\tgjwpb\gy\atl 637
// F:\weioj\hadd\connsh\rwyfvzsopsuiqjnr 647
// E:\ns\mfwj\wqkoki\eez 648
// D:\cfmwafhhgeyawnool 649
// E:\czt\opwip\osnll\c 637
// G:\nt\f 633
// F:\fop\ywzqaop 631
// F:\yay\jc\ywzqaop 631
// D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645
输出:
// rzuwnjvnuz 633 1
// atl 637 1
// rwyfvzsopsuiqjnr 647 1
// eez 648 1
// fmwafhhgeyawnool 649 1
// c 637 1
// f 633 1
// ywzqaop 631 2
说明:
由于D:\cfmwafhhgeyawnool 649的文件名长度超过了16个字符,达到了17,所以第一个字符'c'应该被忽略。
记录F:\fop\ywzqaop 631和F:\yay\jc\ywzqaop 631由于文件名和行号相同,因此被视为同一个错误记录,哪怕它们的路径是不同的。
由于循环记录时,只以第一次出现的顺序为准,后面重复的不会更新它的出现时间,仍以第一次为准,所以D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645不会被记录。
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Queue<String> queue = new LinkedList<>();
Map<String, Integer> map = new LinkedHashMap<>();
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
//【1】获取文件名称(最后一个斜杠后面的带后缀名的部分)
String[] strs = in.nextLine().split(" ");
String[] fileName = strs[0].split("\\\\");
String str = fileName[fileName.length - 1];
//【2】文件名称保留最后16位
if (str.length() > 16) {
str = str.substring(str.length() - 16);
}
//【3】利用文件名称 + 空格 + 行号,拼接成key
String key = str + " " + strs[1];
//【4】只有key不在map中存在,才放入队列中
// 若key在map中存在,此时的key可能已经在队列中,或者被队列从头部移除
if (!map.keySet().contains(key)) {
queue.offer(key);
}
//【5】题意要求:记录最多8条错误记录
if(queue.size() > 8){
queue.poll();
}
//【6】map存放<文件名称+行号,相同错误的数量>
map.put(key, map.getOrDefault(key, 0) + 1);
}
while (!queue.isEmpty()) {
String key = queue.poll(); // 文件名称 + 空格 + 行号
Integer value = map.get(key); // 错误记录的数量
System.out.println(key.split(" ")[0] + " " + key.split(" ")[1] + " " + value);
}
}
}
77777 - HJ25 数据分类处理
// https://www.nowcoder.com/practice/9a763ed59c7243bd8ab706b2da52b7fd
55555 - HJ30 字符串合并处理
// https://www.nowcoder.com/practice/d3d8e23870584782b3dd48f26cb39c8f
// 输入:ab CD
// 输出:3B5D
// 说明:
// 合并后为abCD,按奇数位和偶数位排序后是CDab
// (请注意要按ascii码进行排序,所以C在a前面,D在b前面),转换后为3B5D
// 参考解答:https://blog.nowcoder.net/n/49406199e8494d7c933b11ada425d6f4?f=comment
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String word1 = in.next();
String word2 = in.next();
String word = word1 + word2;
//【1】合并两个字符串
String str = word1 + word2;
//【2】字符串排序
List<Character> list1 = new ArrayList<>(); // 存放奇数位字符
List<Character> list2 = new ArrayList<>(); // 存放偶数位字符
for (int i = 0; i < str.length(); i++) {
if (i % 2 != 0) {
list1.add(str.charAt(i));
} else {
list2.add(str.charAt(i));
}
}
Collections.sort(list1);
Collections.sort(list2);
//【3】排序后重新拼接字符串
StringBuilder builder = new StringBuilder();
// list2.size() >= list1.size(), 偶数要比奇数多
for (int i = 0; i < list2.size(); i++) {
builder.append(list2.get(i));
if (i < list1.size()) { // 防止奇数位字符越界
builder.append(list1.get(i));
}
}
//【4】对字符进行进制转换操作
StringBuilder result = new StringBuilder();
for (Character ch : builder.toString().toCharArray()) {
if (ch.toString().matches("[0-9a-fA-F]")) {
//【1】十六进制转十进制
int num = Integer.parseInt(ch.toString(), 16);
//【2】十进制转二进制
StringBuilder binary = new StringBuilder(Integer.toBinaryString(num));
// 将二进制凑足4位(前面补0)
while (binary.length() < 4) {
binary.insert(0, "0");
}
//【3】字符串翻转
binary.reverse();
//【4】二进制转十进制
int newNum = Integer.parseInt(binary.toString(), 2);
//【5】十进制转十六进制(默认是小写,要转成大写)
String hexString = Integer.toHexString(newNum).toUpperCase();
result.append(hexString);
} else {
// 若字符大于F、f,则保持原字符,因为转不了十进制
result.append(ch);
}
}
System.out.println(result);
}
}
public void test() {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String word1 = in.next();
String word2 = in.next();
String word = word1 + word2;
int length = word.length();
Character[] chars1 = new Character[length / 2];
Character[] chars2 = new Character[length - length / 2];
Character[] chars = new Character[length];
for (int i = 0, m = 0, n = 0; i < word.length(); i++) {
if (i % 2 != 0) {
chars1[m++] = word.charAt(i);
} else {
chars2[n++] = word.charAt(i);
}
}
Arrays.sort(chars1);
Arrays.sort(chars2);
for (int i = 0, m = 0, n = 0; i < chars.length; i++) {
if (i % 2 != 0) {
chars[i] = chars1[m++];
} else {
chars[i] = chars2[n++];
}
}
StringBuilder result = new StringBuilder();
for (Character ch : chars) {
if (ch.toString().matches("[0-9a-fA-F]")) {
int num = Integer.parseInt(ch.toString(), 16);
StringBuilder binaryString = new StringBuilder(Integer.toBinaryString(num));
while (binaryString.length() < 4) {
binaryString.insert(0, "0");
}
binaryString.reverse();
int newNum = Integer.parseInt(binaryString.toString(), 2);
String hexString = Integer.toHexString(newNum).toUpperCase();
result.append(hexString);
} else {
result.append(ch);
}
}
System.out.println(result);
}
}
}
55555 - HJ39 判断两个IP是否属于同一子网
// https://www.nowcoder.com/practice/34a597ee15eb4fa2b956f4c595f03218
// 输入:
// 255.255.255.0
// 192.168.224.256
// 192.168.10.4
// 255.0.0.0
// 193.194.202.15
// 232.43.7.59
// 255.255.255.0
// 192.168.0.254
// 192.168.0.1
// 输出:
// 1
// 2
// 0
// 说明:
// 对于第一个例子:
// 255.255.255.0
// 192.168.224.256
// 192.168.10.4
// 其中IP:192.168.224.256不合法,输出1
// 对于第二个例子:
// 255.0.0.0
// 193.194.202.15
// 232.43.7.59
// 2个与运算之后,不在同一个子网,输出2
// 对于第三个例子,2个与运算之后,如题目描述所示,在同一个子网,输出0
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
String[] Netmask = in.next().split("\\.");
String[] ip1 = in.next().split("\\.");
String[] ip2 = in.next().split("\\.");
String[] binaryMast = new String[Netmask.length];
int result = 0;
// 依次遍历子网掩码与IP的每段数字
for (int i = 0; i < Netmask.length; i++) {
int num = Integer.parseInt(Netmask[i]);
int num1 = Integer.parseInt(ip1[i]);
int num2 = Integer.parseInt(ip2[i]);
//【1】每段子网掩码与IP的都要求在0 - 255之间
if (num < 0 || num > 255 || num1 < 0 || num1 > 255 || num2 < 0 || num2 > 255) {
result = 1;
break;
}
//【2】将每段子网掩码转换为8位,不足8位的前面加0补齐,最后放入binaryMast数组中
StringBuilder binary = new StringBuilder(Integer.toBinaryString(num));
while (binary.length() < 8) {
binary.insert(0, "0");
}
binaryMast[i] = binary.toString();
//【3】IP地址分别与它们的子网掩码进行逻辑“与”运算(直接采用运算符&,而不是先转换为二进制后再运算)
// 并将运算结果直接放入IP数组
ip1[i] = String.valueOf(Integer.parseInt(Netmask[i]) & Integer.parseInt(ip1[i]));
ip2[i] = String.valueOf(Integer.parseInt(Netmask[i]) & Integer.parseInt(ip2[i]));
}
//【4】子网掩码的二进制字符串前缀为网络号,都由‘1’组成;后缀为主机号,都由'0'组成(可以全为1 或者 全为0)
// 比如:11111111, 11111111, 11111100, 00000000
StringBuilder sb = new StringBuilder();
for (String s : binaryMast) {
sb.append(s);
}
int index1 = sb.lastIndexOf("1");
int index0 = sb.lastIndexOf("0", index1); // 若不存在1,index1返回-1,此时index0也会返回-1,即子网掩码的所有数字都为0
// 若最后一个1之前存在0,则不满足所有1在前面,所有0在后面的规则。即格式非法
if(index0 != -1 && index1 != -1 && index0 < index1){
result = 1;
}
if (result == 1) {
System.out.println(result);
continue;
}
//【5】两个IP地址与子网掩码的AND运算后,判断它们的运算结果是否一样
if(!Arrays.equals(ip1, ip2)){
result = 2;
}
// for (int i = 0; i < ip1.length; i++) {
// if (Integer.parseInt(ip1[i]) != Integer.parseInt(ip2[i])) {
// result = 2;
// break;
// }
// }
System.out.println(result);
}
}
}
HJ42 学英语 - 11111
// https://www.nowcoder.com/practice/1364723563ab43c99f3d38b5abef83bc
// 具体规则如下:
// 1.在英语读法中三位数字看成一整体,后面再加一个计数单位。从最右边往左数,三位一单位,例如12,345 等
// 2.每三位数后记得带上计数单位 分别是thousand, million, billion.
// 3.公式:百万以下千以上的数 X thousand X, 10亿以下百万以上的数:X million X thousand X, 10 亿以上的数:X billion X million X thousand X. 每个X分别代表三位数或两位数或一位数。
// 4.在英式英语中百位数和十位数之间要加and,美式英语中则会省略,我们这个题目采用加上and,百分位为零的话,这道题目我们省略and
// 下面再看几个数字例句:
// 22: twenty two
// 100: one hundred
// 145: one hundred and forty five
// 1,234: one thousand two hundred and thirty four
// 8,088: eight thousand (and) eighty eight (注:这个and可加可不加,这个题目我们选择不加)
// 486,669: four hundred and eighty six thousand six hundred and sixty nine
// 1,652,510: one million six hundred and fifty two thousand five hundred and ten
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
// 19以内数字对应的英文
String[] nums = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
};
// 十位数对应的英文
String[] num10 = {"zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};
// 每三个0后,都会添加上单位,对应的英文
String[] units = {"", "thousand", "million", "billion"};
int target = in.nextInt();
List<String> list = new ArrayList<>();
int unitIndex = 0;
while (target > 0) {
//【1】大于三位数后,首先都需要加上单位:"thousand", "million", "billion"
if (unitIndex > 0) {
list.add(units[unitIndex]);
}
//【2】每轮遍历都是从后往前取三位数
int num = target % 1000;
//【3】判断后两位数是否小于20
int lastTwoNum = num % 100;
if (lastTwoNum < 20) {
//【3.1】添加后两位数字对应的英文。若小于20,后两位数直接从nums中获取对应的英文
if (lastTwoNum != 0) {
list.add(nums[lastTwoNum]);
}
//【3.2】添加第一位数字对应的英文
int firstNum = num / 100;
if (firstNum != 0) {
// 只有当后两位不为0时,才需要添加"and"
if (lastTwoNum != 0) {
list.add("and");
}
list.add("hundred");
list.add(nums[firstNum]);
}
//【4】后两位数大于等于20的场景
} else {
//【4.1】添加个位数,直接根据个位数到nums中获取
if (num % 10 != 0) {
list.add(nums[num % 10]);
}
//【4.2】添加十位数
num = num / 10;
if (num % 10 != 0) {
list.add(num10[num % 10]);
}
//【4.3】添加百位数
num = num / 10;
if (num % 10 != 0) {
list.add("and"); // 此时后两位肯定不为0,所以直接添加上"and"
list.add("hundred");
list.add(nums[num % 10]);
}
}
// 每轮遍历完成后,去掉最后的三位数字
target = target / 1000;
// 单位索引向后移动
unitIndex++;
}
StringBuilder result = new StringBuilder();
//【5】从后向前获取数据
for (int i = list.size() - 1; i >= 0; i--) {
result.append(list.get(i) + " ");
}
// trim():去掉首位空格
System.out.println(result.toString().trim());
}
}
}
55555 - HJ68 成绩排序
// https://www.nowcoder.com/practice/8e400fd9905747e4acc2aeed7240978b
// 描述
// 给定一些同学的信息(名字,成绩)序列,请你将他们的信息按照成绩从高到低或从低到高的排列,相同成绩
// 都按先录入排列在前的规则处理。
// 例示:
// jack 70
// peter 96
// Tom 70
// smith 67
// 从高到低 成绩
// peter 96
// jack 70
// Tom 70
// smith 67
// 从低到高
// smith 67
// jack 70
// Tom 70
// peter 96
// 注:0代表从高到低,1代表从低到高
// 数据范围:人数:1\le n \le 200\1≤n≤200
// 进阶:时间复杂度:O(nlogn)\O(nlogn) ,空间复杂度:O(n)\O(n)
// 输入描述:
// 第一行输入要排序的人的个数n,第二行输入一个整数表示排序的方式,之后n行分别输入他们的名字和成绩,以一个空格隔开
// 输出描述:
// 按照指定方式输出名字和成绩,名字和成绩之间以一个空格隔开
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
int num = in.nextInt();
// 0是降序, 1是升序
int flag = in.nextInt();
Map<Integer, String> map = new HashMap<>();
int[][] scores = new int[num][2];
//【1】采用map和二维数组分别存放学生姓名和学生成绩
for (int index = 0; index < num; index++) {
//【1.1】Map存放:<编号(录入顺序),学生名字>
String name = in.next();
map.put(index, name);
//【1.2】二维数组score存放:[编号(录入顺序)][学生成绩]
int score = in.nextInt();
scores[index][0] = index;
scores[index][1] = score;
}
//【2】按照成绩从高到低 或 从低到高的排列
Arrays.sort(scores, (o1, o2) -> {
if (flag == 0) {
return o2[1] - o1[1]; // 按第二列降序排列, 如果相等的话,返回0,顺序不变
} else {
return o1[1] - o2[1]; // 按第二列升序排列
}
});
//【3】map.get(scores[i][0]):根据学生编号获取学生姓名
for (int i = 0; i < num; i++) {
System.out.println(map.get(scores[i][0]) + " " + scores[i][1]);
}
}
}
// 解答失败:原因是学生姓名可以有重复的,但是map的key不能重复
public void test2() {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
int num = in.nextInt();
int flag = in.nextInt();
Map<String, Integer> map = new LinkedHashMap<>();
for (int i = 0; i < num; i++) {
String name = in.next();
Integer score = in.nextInt();
map.put(name, score);
}
Integer maxValue = map.values().stream().max(Integer::compareTo).get();
Integer minValue = map.values().stream().min(Integer::compareTo).get();
Integer max = maxValue;
Integer min = minValue;
Map<String, Integer> maxMap = new LinkedHashMap<>();
while (max >= min) {
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue().equals(max)) {
maxMap.put(entry.getKey(), entry.getValue());
}
}
max--;
}
Map<String, Integer> minMap = new LinkedHashMap<>();
while (minValue <= maxValue) {
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue().equals(minValue)) {
minMap.put(entry.getKey(), entry.getValue());
}
}
minValue++;
}
if (flag == 0) {
for (Map.Entry<String, Integer> entry : maxMap.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
} else {
for (Map.Entry<String, Integer> entry : minMap.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
}
}
}
HJ88 扑克牌大小 - 11111
// https://www.nowcoder.com/practice/d290db02bacc4c40965ac31d16b1c3eb
// 扑克牌游戏大家应该都比较熟悉了,一副牌由54张组成,含3~A、2各4张,小王1张,大王1张。牌面从小到大用如下字符和字符串表示(其中,小写joker表示小王,大写JOKER表示大王):
// 3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER
// 输入两手牌,两手牌之间用"-"连接,每手牌的每张牌以空格分隔,"-"两边没有空格,如:4 4 4 4-joker JOKER。
// 请比较两手牌大小,输出较大的牌,如果不存在比较关系则输出ERROR。
// 基本规则:
// (1)输入每手牌可能是个子、对子、顺子(连续5张)、三个、炸弹(四个)和对王中的一种,不存在其他情况,由输入保证两手牌都是合法的,顺子已经从小到大排列;
// (2)除了炸弹和对王可以和所有牌比较之外,其他类型的牌只能跟相同类型的存在比较关系(如,对子跟对子比较,三个跟三个比较),不考虑拆牌情况(如:将对子拆分成个子);
// (3)大小规则跟大家平时了解的常见规则相同,个子、对子、三个比较牌面大小;顺子比较最小牌大小;炸弹大于前面所有的牌,炸弹之间比较牌面大小;对王是最大的牌;
// (4)输入的两手牌不会出现相等的情况。
// 数据范围:字符串长度:3 ≤ s ≤ 10
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Map<String, Integer> map = new HashMap<String, Integer>(){{
put("3", 3);
put("4", 4);
put("5", 5);
put("6", 6);
put("7", 7);
put("8", 8);
put("9", 9);
put("10", 10);
put("J", 11);
put("Q", 12);
put("K", 13);
put("A", 14);
put("2", 15);
put("joker", 16);
put("JOKER", 17);
}};
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) {
// 题意:个子、对子、顺子(连续5张)、三个、炸弹(四个)的牌数分别是1、2、5、3、4
// 即可以通过手牌长度判断其类型。长度相等,则类型相同
String[] strs = in.nextLine().split("-");
String cards1 = strs[0];
String cards2 = strs[1];
String[] c1 = cards1.split(" ");
String[] c2 = cards2.split(" ");
String result = "";
//【1】若其中一个是王炸,直接输出即可(因为输入的两手牌不会出现相等的情况)
if(cards1.equals("joker JOKER")){
result = cards1;
} else if(cards2.equals("joker JOKER")){
result = cards2;
//【2】若两手牌都是四张,说明它们都是炸弹,直接比较首位字符的大小即可
}else if(c1.length == c2.length && c1.length == 4){
result = map.get(c1[0]) > map.get(c2[0]) ? cards1 : cards2;
//【3】若其中一手牌是炸弹,因为炸弹比其他类型的牌都大,所以直接输出即可
}else if(c1.length == 4){
result = cards1;
} else if(c2.length == 4){
result = cards2;
//【4】两手牌的长度一致时,表明是同类型的手牌(其他类型),直接比较它们的首位字符大小即可。
}else if(c1.length == c2.length){
result = map.get(c1[0]) > map.get(c2[0]) ? cards1 : cards2;
//【5】不存在比较关系
}else{
result = "ERROR";
}
System.out.println(result);
}
}
}
55555 - HJ89 24点运算
// https://www.nowcoder.com/practice/7e124483271e4c979a82eb2956544f9d
// 计算24点是一种扑克牌益智游戏,随机抽出4张扑克牌,通过加(+),减(-),乘(*), 除(/)四种运算法则计算得到整数24,
// 本问题中,扑克牌通过如下字符或者字符串表示,其中,小写joker表示小王,大写JOKER表示大王:
// 3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER
// 本程序要求实现:输入4张牌,输出一个算式,算式的结果为24点。
// 详细说明:
// 1.运算只考虑加减乘除运算,没有阶乘等特殊运算符号,没有括号,友情提醒,整数除法要当心,是属于整除,比如2/3=0,3/2=1;
// 2.牌面2~10对应的权值为2~10, J、Q、K、A权值分别为为11、12、13、1;
// 3.输入4张牌为字符串形式,以一个空格隔开,首尾无空格;如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;
// 4.输出的算式格式为4张牌通过+-*/四个运算符相连,中间无空格,4张牌出现顺序任意,只要结果正确;
// 5.输出算式的运算顺序从左至右,不包含括号,如1+2+3*4的结果为24,2 A 9 A不能变为(2+1)*(9-1)=24
// 6.如果存在多种算式都能计算得出24,只需输出一种即可,如果无法得出24,则输出“NONE”表示无解。
// 7.因为都是扑克牌,不存在单个牌为0的情况,且没有括号运算,除数(即分母)的数字不可能为0
参考解答:https://blog.nowcoder.net/n/c202fc07b90a4220b61277c7c2e911c2?f=comment
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static Map<String, Integer> map = new HashMap<String, Integer>() {{
put("A", 1);
put("2", 2);
put("3", 3);
put("4", 4);
put("5", 5);
put("6", 6);
put("7", 7);
put("8", 8);
put("9", 9);
put("10", 10);
put("J", 11);
put("Q", 12);
put("K", 13);
}};
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) {
String card = in.nextLine();
String[] cards = card.split(" ");
// 如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算
if (card.contains("joker") || card.contains("JOKER")) {
System.out.println("ERROR");
} else if (!dfs(cards, 0, 0, "")) {
System.out.println("NONE");
}
}
}
public static boolean dfs(String[] cards, int start, int res, String path) {
//【1】终止条件:表达式计算结果为24,且横向遍历整个数组完成
if (res == 24 && start == cards.length) {
System.out.println(path);
return true;
}
//【2】横向遍历4张手牌
for (int index = 0; index < cards.length; index++) {
//【2.1】临时保存当前位置的牌
String card = cards[index];
// 若当前位置的牌未被使用过
if (!card.equals("")) {
//【2.2】首先标记该牌被使用过,防止纵向递归过程中,再次使用该牌
cards[index] = "";
int num = map.get(card);
//【2.3】若是第一张牌,则直接加入结果集path
if (start == 0) {
if (dfs(cards, start + 1, num, path + card) ||
dfs(cards, start + 1, num, path + card) ||
dfs(cards, start + 1, num, path + card) ||
dfs(cards, start + 1, num, path + card)) {
return true;
}
//【2.4】若不是第一张牌,则分别加上+-*/后,再加入结果集path,同时更新res
} else {
if(dfs(cards, start + 1, res + num, path + "+" + card) ||
dfs(cards, start + 1, res - num, path + "-" + card) ||
dfs(cards, start + 1, res * num, path + "*" + card) ||
dfs(cards, start + 1, res / num, path + "/" + card)) {
return true;
}
}
//【2.5】回溯,恢复当前位置原先的牌
cards[index] = card;
}
}
return false;
}
}
55555 - HJ93 数组分组
// https://www.nowcoder.com/practice/9af744a3517440508dbeb297020aca86
// 输入int型数组,询问该数组能否分成两组,使得两组中各元素加起来的和相等,并且,
// 所有5的倍数必须在其中一个组中,所有3的倍数在另一个组中(不包括5的倍数),不是5的倍数也不是3的倍数能放在任意一组,
// 可以将数组分为空数组,能满足以上条件,输出true;不满足时输出false
// 输入:3
// 3 5 8
// 输出:false
// 说明:由于3和5不能放在同一组,所以不存在一种分法
// 输入:4
// 1 5 -5 1
// 输出:true
// 说明:
// 第一组:5 -5 1
// 第二组:1
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) {
int num = in.nextInt();
int sum3 = 0; // 所有3的倍数的和
int sum5 = 0; // 所有5的倍数的和
List<Integer> list = new LinkedList<>(); // 存放既不是3的倍数、又不是5的倍数的元素
for (int i = 0; i < num; i++) {
int value = in.nextInt();
if (value % 3 == 0) {
sum3 = sum3 + value;
} else if (value % 5 == 0) {
sum5 = sum5 + value;
} else {
list.add(value);
}
}
boolean result = dfs(list, 0, sum3, sum5);
System.out.println(result);
}
}
public static boolean dfs(List<Integer> list, int index, int sum3, int sum5) {
// 终止条件:遍历完list中所有元素,判断sum3与sum5是否相等
if(index == list.size()){
return sum3 == sum5;
}
return dfs(list, index+1, sum3 + list.get(index), sum5)
|| dfs(list, index+1, sum3, sum5 + list.get(index));
}
}
55555 - HJ95 人民币转换
// https://www.nowcoder.com/practice/00ffd656b9604d1998e966d555005a4b
// 考试题目和要点:
// 1、中文大写金额数字前应标明“人民币”字样。中文大写金额数字应用壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整等字样填写。
// 2、中文大写金额数字到“元”为止的,在“元”之后,应写“整字,如532.00应写成“人民币伍佰叁拾贰元整”。在”角“和”分“后面不写”整字。
// 3、阿拉伯数字中间有“0”时,中文大写要写“零”字,阿拉伯数字中间连续有几个“0”时,中文大写金额中间只写一个“零”字,如6007.14,应写成“人民币陆仟零柒元壹角肆分“。
// 4、10应写作“拾”,100应写作“壹佰”。例如,1010.00应写作“人民币壹仟零拾元整”,110.00应写作“人民币壹佰拾元整”
// 5、十万以上的数字接千不用加“零”,例如,30105000.00应写作“人民币叁仟零拾万伍仟元整”
// 输入:151121.15
// 输出:人民币拾伍万壹仟壹佰贰拾壹元壹角伍分
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
String[] sources = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
String[] units = {"", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟", "万"};
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextDouble()) {
double rmb = in.nextDouble();
//
String rmbs = String.format("%.2f", rmb) + "";
String[] targets = rmbs.split("\\.");
String target = targets[0];
String decimals = targets[1];
StringBuilder result = new StringBuilder();
//【1】从左往右遍历数字、并加上units中的对应单位。通过target的索引可以判断当前位置的单位
for (int leftIndex = 0, unitIndex = target.length() - 1; leftIndex < target.length(); leftIndex++, unitIndex--) {
//【2】当前数字不为0
if (target.charAt(leftIndex) != '0') {
//【2.1】若当前数字为1,同时当前位置对应的单位为"拾",则直接添加上"拾"
if (target.charAt(leftIndex) == '1' && units[unitIndex].equals("拾")) {
result.append("拾");
//【2.2】其余场景:先添加数字对应的中文金额,再添加单位
} else {
int index = target.charAt(leftIndex) - '0';
result.append(sources[index]);
result.append(units[unitIndex]);
}
//【3】当前数字为0
} else {
//【3.1】首先循环遍历连续出现的0。题意三要求:阿拉伯数字中间连续有几个"0"时,中文大写金额中间只写一个"零"字
while (leftIndex < target.length() && target.charAt(leftIndex) == '0') {
// 若当前位置对应的单位为"万" 或者 "亿",需要将这两个单位加入结果集。比如X万、X亿、X万亿、X万万亿
if (units[unitIndex].equals("万") || units[unitIndex].equals("亿")) {
result.append(units[unitIndex]);
}
leftIndex++;
unitIndex--;
}
//【3.2】因为while循环中最后一次i++、unitIndex--后不满足条件。所以此处需要回退一步。
// 不然外层for会再一次i++、unitIndex--,导致漏掉部分数据
leftIndex--;
unitIndex++;
//【3.3】判断是否已到字符串尾部
if (leftIndex == target.length() - 1) {
break;
}
//【3.4】若不是"万"位 或者 "亿"位,则添加上"零"。满足题意5:十万以上的数字接千不用加"零"
// unitIndex % 4 == 0对应单位都是"万" 或者 "亿"
// 若"万"位是0,不需要单独添加"零",会直接读取为XX拾万
// 10100(壹万零壹佰)、200110(贰拾万零壹佰拾元)、1001(壹仟零壹)、1010(壹仟零拾)
if (unitIndex % 4 != 0) {
result.append("零");
}
}
}
//【4】若小数都是0,则添加"元整",否则添加"元"
if (result.length() != 0) {
if (decimals.equals("00")) {
result.append("元整");
} else {
result.append("元");
}
}
//【5】转换小数位上的两个数字
if (!decimals.equals("00")) {
char firstNum = decimals.charAt(0);
if (firstNum != '0') {
result.append(sources[firstNum - '0']).append("角");
}
char secendNum = decimals.charAt(1);
if (secendNum != '0') {
result.append(sources[secendNum - '0']).append("分");
}
}
System.out.println("人民币" + result);
}
}
}
困难
HJ28 素数伴侣 - 22222
// https://www.nowcoder.com/practice/b9eae162e02f4f928eac37d7699b352e
// 题目描述
// 若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,
// 从已有的 N ( N 为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,
// 例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。
// 输入:
// 有一个正偶数 n ,表示待挑选的自然数的个数。后面给出 n 个具体的数字。
// 输出:
// 输出一个整数 K ,表示你求得的“最佳方案”组成“素数伴侣”的对数。
// 数据范围:1 ≤ n ≤ 100 ,输入的数据大小满足2 ≤ val ≤ 30000
// 输入描述:
// 输入说明
// 1 输入一个正偶数n
// 2 输入n个整数
// 输出描述:
// 求得的“最佳方案”组成“素数伴侣”的对数
// 输入:4
// 2 5 6 13
// 输出:2
// 输入:2
// 3 6
// 输出:0
import java.util.Scanner;
import java.util.ArrayList;
public class Main {
static int max = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
// 用于记录输入的n个整数
int[] arr = new int[n];
// 用于存储所有的奇数
ArrayList<Integer> odds = new ArrayList<>();
// 用于存储所有的偶数
ArrayList<Integer> evens = new ArrayList<>();
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
// 将奇数添加到odds
if (arr[i] % 2 == 1) odds.add(arr[i]);
// 将偶数添加到evens
if (arr[i] % 2 == 0) evens.add(arr[i]);
}
// 下标对应已经匹配的偶数的下标,值对应这个偶数的伴侣
int[] matcheven = new int[evens.size()];
// 记录伴侣的对数
int count = 0;
for (int j = 0; j < odds.size(); j++) {
// 用于标记对应的偶数是否查找过
boolean[] flags = new boolean[evens.size()];
// 如果匹配上,则计数加1
if (find(odds.get(j), matcheven, evens, flags)) {
count++;
}
}
System.out.println(count);
}
}
//判断奇数x能否找到伴侣
private static boolean find(int x, int[] matcheven, ArrayList<Integer> evens, boolean[] flags) {
for (int i = 0; i < evens.size(); i++) {
// 该位置偶数没被访问过,并且能与x组成素数伴侣
if (isPrime(x + evens.get(i)) && flags[i] == false) {
flags[i] = true;
/*如果i位置偶数还没有伴侣,则与x组成伴侣,如果已经有伴侣,并且这个伴侣能重新找到新伴侣,
则把原来伴侣让给别人,自己与x组成伴侣*/
if (matcheven[i] == 0 || find(matcheven[i], matcheven, evens, flags)) {
matcheven[i] = x;
return true;
}
}
}
return false;
}
// 判断x是否是素数
private static boolean isPrime(int x) {
if (x == 1) return false;
// 如果能被2到根号x整除,则一定不是素数
for (int i = 2; i <= (int)Math.sqrt(x); i++) {
if (x % i == 0) return false;
}
return true;
}
}
HJ44 Sudoku
// https://www.nowcoder.com/practice/78a1a4ebe8a34c93aac006c44f6bf8a1
// 问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,
// 并且满足每一行、每一列、每一个3X3粗线宫内的数字均含1-9,并且不重复
// 数据范围:输入一个 9*9 的矩阵
// 输入描述:
// 包含已知数字的9X9盘面数组[空缺位以数字0表示]
// 输出描述:
// 完整的9X9盘面数组
输入:
0 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
0 4 5 2 7 6 8 3 1
输出:
5 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
9 4 5 2 7 6 8 3 1
public class HuaweiHJ44Sudoku {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
char[][] nums = new char[9][9];
int row = 0;
// 先判断是否还有下一行输入
while (in.hasNextLine()) {
// str接入整行输入参数
String str = in.nextLine();
String[] strs = str.split(" ");
// 字符串数组 转 字符数组
char[] temp = new char[9];
for (int i = 0; i < strs.length; i++) {
temp[i] = strs[i].charAt(0);
}
// 赋值给九宫格的每行
nums[row++] = temp;
}
dfs(nums);
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums[0].length; j++) {
System.out.print(nums[i][j] + " ");
}
System.out.println();
}
}
private static boolean dfs(char[][] nums) {
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums[0].length; j++) {
if (nums[i][j] != '0') continue;
for (char k = '1'; k <= '9'; k++) {
// 当前坐标放字符k,判断是否有重复
if (isValidSudoku(nums, i, j, k)) {
nums[i][j] = k;
// 递归判断每个位置
if (dfs(nums)) {
return true;
}
nums[i][j] = '0';
}
}
// 当前坐标放[1 - 9]都不满足条件,则回溯到上一步
return false;
}
}
return true;
}
private static boolean isValidSudoku(char[][] nums, int x, int y, char value) {
// 同行是否重复
for (int i = 0; i < 9; i++) {
if (nums[x][i] == value) {
return false;
}
}
// 同列是否重复
for (int j = 0; j < 9; j++) {
if (nums[j][y] == value) {
return false;
}
}
// 九宫格是否重复
int startRow = (x / 3) * 3;
int startCol = (y / 3) * 3;
for (int i = startRow; i < startRow + 3; i++) {
for (int j = startCol; j < startCol + 3; j++) {
if (nums[i][j] == value) {
return false;
}
}
}
return true;
}
}
HJ98 自动售货系统 - 2
https://www.nowcoder.com/practice/cd82dc8a4727404ca5d32fcb487c50bf