华为机试全套代码详解HJ1-HJ20(更新中) – 三郎君的日常

Java基础 · 2022年5月17日 0

华为机试全套代码详解HJ1-HJ20(更新中)

package HuaWei;
/*
Author:Sanro
Time:2022.05.15 14:01:01
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
•输入一个字符串,请按长度为8拆分每个输入字符串并进行输出;

•长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。
输入描述:
连续输入字符串(每个字符串长度小于等于100)

输出描述:
依次输出所有分割后的长度为8的新字符串

示例1
输入:
abc

输出:
abc00000

*/
import java.util.Scanner;

public class HJ1字符串最后一个单词长度 {
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        int i = s.length() - 1;
        int t = 0;
        while(i >= 0 && s.charAt(i) != ' '){
            t++;
            i--;
        }
        System.out.println(t);
    }
}
ackage HuaWei;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class HJ2计算某字符出现次数 {
        public static void main(String[] args){
            Scanner sc = new Scanner(System.in);
            String in1 =sc.nextLine().toLowerCase();
            String in2 = sc.nextLine().toLowerCase();
            // 把所有in2字符全替换成“”,组成新字符串
            String str = in1.replaceAll(in2,"");
            // 原始字符串长度 - 新字符串长度 = 字符出现的次数
            System.out.println(in1.length()-str.length());
        }

}
package HuaWei;

import java.util.Arrays;
import java.util.Scanner;

public class HJ3数字去重 {
        public static void main(String[] args){
            Scanner in = new Scanner(System.in);
            while(in.hasNext()){
                int count = in.nextInt();    //随机数总数
                int[] data = new int[count];
                for(int i=0; i < count; i++)    //读入生成的随机数
                    data[i] = in.nextInt();

                Arrays.sort(data);    //使用库函数排序
                System.out.println(data[0]);    //打印排序后的第一个数(必不重复)
                for(int i=1; i < count; i++){    //打印其他数字,需与前面数字比较,不重复才能打印
                    if(data[i] != data[i-1])
                        System.out.println(data[i]);
                }
            }
        }




//        public static void main(String[] args) {
//            Scanner sc = new Scanner(System.in);
//            //获取个数
//            int num = sc.nextInt();
//            //创建TreeSet进行去重排序
//            TreeSet set = new TreeSet();
//            //输入
//            for(int i =0 ; i < num ;i++){
//                set.add(sc.nextInt());
//            }
//
//            //输出
//            Iterator iterator = set.iterator();
//            while (iterator.hasNext()){
//                System.out.println(iterator.next());
//            }
//        }

}
package HuaWei;

import java.util.Scanner;

public class HJ4字符串补位分割 {
    public static void main(String[] args) {


        /**
         *1.输入字符串大于8时,递归截取前8位输入,直至小于8位时进入循环补0
         *2.字符串小于8时直接跳到循环补0操作,补满至8位时打印输出
         *3.正好等于8位或为空字符串时,直接打印输出
         */
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            String s=in.nextLine();
            while(s.length()>8){
                System.out.println(s.substring(0,8));
                s=s.substring(8);
            }
            while(s.length()<8&&s.length()>0){
                s+="0";
            }
            System.out.println(s);
        }
    }
}

//        Scanner in = new Scanner(System.in);
//        String str = in.nextLine();
//        char[] chars = str.toCharArray();
//        if (chars.length % 8 == 0) {   //长度是8倍数 循环输出
//            for (int i = 0; i < chars.length; i++) {
//                System.out.print(chars[i]);
//                if ((i + 1) % 8 == 0) {
//                    System.out.println();
//                }
//            }
//        }
//        //长度不是8的倍数则补
//        else {
//            if (chars.length < 8) {
//                char[] chars1 = new char[8];
//                for (int i=0;i<8;i++){
//                    if(i<chars.length) chars1[i]=chars[i];
//                    else chars1[i] = '0';
//                }
//                for (int i=0;i<8;i++){
//                    System.out.print(chars1[i]);
//                }
//
//            }
//            else {
//                int m = chars.length % 8;
//                int len = chars.length + (8 - m);
//                char[] chars1 = new char[len];
//                for (int i = 0; i < chars1.length; i++) {
//                    if (i < chars.length) {
//                        chars1[i] = chars[i];
//                    }else chars1[i] = '0';
//                }
//                    for (int i = 0; i < chars1.length; i++) {
//                        System.out.print(chars1[i]);
//                        if ((i + 1) % 8 == 0) {
//                            System.out.println();
//                        }
//                    }
//                }
//            }
//        }
package HuaWei;
//16进制的表示 0x(0x是固定写法)数字或者字母(A-F)可以是小写,
// 英文字母A,B,C,D,E,F分别表示数字10~15。
//        逢16进1,
//        例如:0xAF=175 的十进制如下:
//        相当于 10*16¹ + 15*16º = 160 +15 =175
/*
Author:Sanro
Time:2022.05.15 14:01:01
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。

数据范围:保证结果在 1 \le n \le 2^{31}-1 \1≤n≤2
31
 −1
输入描述:
输入一个十六进制的数值字符串。

输出描述:
输出该数值的十进制字符串。不同组的测试用例用\n隔开。

示例1
输入:
0xAA
复制
输出:
170

*/

import java.util.Scanner;
public class HJ5进制转换 {
    public static void main(String[] args){
         Scanner scan=new Scanner(System.in);
         while(scan.hasNext()){
             String str=scan.next();
             //解法二: 直接用Integer.parseInt("String", 进制) 进行转换。
            System.out.println(Integer.parseInt(str.replaceAll("0x",""),16));
         }
    }
}

//        Scanner in = new Scanner(System.in);
//        while(in.hasNext()){
//            String str = in.nextLine();
//            String s1 = str.substring(2);
//            int a = Integer.valueOf(s1,16);
//            System.out.println(a);
package HuaWei;
/*
Author:Sanro
Time:2022.05.15 14:01:01
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )


数据范围: 1 \le n \le 2 \times 10^{9} + 14 \1≤n≤2×10
9
 +14
输入描述:
输入一个整数

输出描述:
按照从小到大的顺序输出它的所有质数的因子,以空格隔开。

示例1
输入:
180
复制
输出:
2 2 3 3 5

*/
import java.util.Scanner;

/**
 * 【质数因子】
 *  描述:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)
 *  (如180的质因子为2 2 3 3 5 )
 *  【重要知识点】:每一个正整数的质数因子都不会超过本身的算术平方根+1
 */
public class HJ6质数因子 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int nextInt = sc.nextInt();
        // 临时保存输入的初始值
        int temp = nextInt;
        // 输入值开平方根
        Double sqrt = Math.sqrt(nextInt);

        for (int k = 2; k <= sqrt.intValue() + 1;) {
            if (nextInt % k == 0) {
                nextInt = nextInt / k;
                System.out.print(k + " ");
            } else {
                k++;
            }
        }

        if (temp == nextInt) {
            // 本身就是质数
            System.out.println(temp);
        } else if (nextInt != 1) {
            System.out.println(nextInt);
        }
    }
}

package HuaWei;
/*
Author:Sanro
Time:2022.05.15 14:01:01
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于 0.5 ,向上取整;小于 0.5 ,则向下取整。

数据范围:保证输入的数字在 32 位浮点数范围内
输入描述:
输入一个正浮点数值

输出描述:
输出该数值的近似整数值

示例1
输入:
5.5
复制
输出:
6
复制
说明:
0.5>=0.5,所以5.5需要向上取整为6
示例2
输入:
2.499
复制
输出:
2
复制
说明:
0.499<0.5,2.499向下取整为2
*/
import java.util.Scanner;

public class HJ7近似值 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        float num = scanner.nextFloat();
        //System.out.println(num);
        int num_int = (int)num;
        float num_res = num -num_int;
        //System.out.println(num_res);
        if (num_res>0.4999){
            System.out.println(num_int+1);
        }else System.out.println(num_int);

    }
}
package HuaWei;
/*
Author:Sanro
Time:2022.05.15 14:01:01
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
数据表记录包含表索引index和数值value(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照index值升序进行输出。


提示:
0 <= index <= 11111111
1 <= value <= 100000

输入描述:
先输入键值对的个数n(1 <= n <= 500)
接下来n行每行输入成对的index和value值,以空格隔开

输出描述:
输出合并后的键值对(多行)

示例1
输入:
4
0 1
0 2
1 2
3 4
复制
输出:
0 3
1 2
3 4
复制
示例2
输入:
3
0 1
0 2
8 9
复制
输出:
0 3
8 9

*/
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
//数据表记录包含表索引index和数值value(int范围的正整数),
// 请对表索引相同的记录进行合并,
// 即将相同索引的数值进行求和运算,输出按照index值升序进行输出。
//        提示:
//        0 <= index <= 11111111
//        1 <= value <= 100000
//
//        输入描述:
//        先输入键值对的个数n(1 <= n <= 500)
//        接下来n行每行输入成对的index和value值,以空格隔开
//
//        输出描述:
//        输出合并后的键值对(多行)
//输入:
//4
//0 1
//0 2
//1 2
//3 4
//
//输出:
//0 3
//1 2
//3 4
public class HJ8合并表记录HashMap {
    //哈希表重中之重
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int tableSize = scanner.nextInt();
        Map<Integer, Integer> table = new HashMap<>(tableSize);
        for (int i = 0; i < tableSize; i++) {
            int key = scanner.nextInt();
            int value = scanner.nextInt();
            if (table.containsKey(key)) {
                table.put(key, table.get(key) + value);
            } else {
                table.put(key, value);
            }
        }
        for (Integer key : table.keySet()) {
            System.out.println( key + " " + table.get(key));
        }
    }
}
package HuaWei;
/*
Author:Sanro
Time:2022.05.15 14:01:01
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
输入一个 int 型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。
保证输入的整数最后一位不是 0 。

数据范围: 1 \le n \le 10^{8} \1≤n≤10
8

输入描述:
输入一个int型整数

输出描述:
按照从右向左的阅读顺序,返回一个不含重复数字的新的整数

示例1
输入:
9876673
复制
输出:
37689

*/
import org.omg.Messaging.SyncScopeHelper;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/*
描述
输入一个 int 型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。
保证输入的整数最后一位不是 0 。

数据范围: 1 \le n \le 10^{8} \1≤n≤10

输入描述:
输入一个int型整数

输出描述:
按照从右向左的阅读顺序,返回一个不含重复数字的新的整数

示例1
输入:
9876673

输出:
37689
*/
public class HJ9提取不重复整数 {
    //下面正确思路:先倒置数组  再放进Map中  最后去重输出
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        char[] c = sc.nextLine().toCharArray();
        char[] c_d = new char[c.length];
        //倒置数组
        for (int i= 0; i<c.length ; i++){
            c_d[c.length-i-1] = c[i];
        }
        //放入map
        Map<Integer, Character> table = new HashMap<>();
        for (int i = 0; i < c.length; i++) {
          if (table.containsValue(c_d[i])) continue;
            else    table.put( i,  c_d[i]);
        }
        //去重输出
        for (int i = 0; i< c.length ;i++){
            if (table.get(i)!=null) System.out.print(table.get(i));
            else continue;
        }

    }
}
/*
正确思路:先倒置 再去重输出
2344356
6534432
65342
错误思路:先去重 再倒置输出
2344356
23456
65432
*/
package HuaWei;
/*
Author:Sanro
Time:2022.05.15 14:01:01
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
编写一个函数,计算字符串中含有的不同字符的个数。字符在 ASCII 码范围内( 0~127 ,包括 0 和 127 ),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次
例如,对于字符串 abaca 而言,有 a、b、c 三种不同的字符,因此输出 3 。

数据范围: 1 \le n \le 500 \1≤n≤500
输入描述:
输入一行没有空格的字符串。

输出描述:
输出 输入字符串 中范围在(0~127,包括0和127)字符的种数。

示例1
输入:
abc
复制
输出:
3
复制
示例2
输入:
aaa
复制
输出:
1
复制
*/
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/*
描述
编写一个函数,计算字符串中含有的不同字符的个数。字符在 ASCII 码范围内( 0~127 ,包括 0 和 127 ),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次
例如,对于字符串 abaca 而言,有 a、b、c 三种不同的字符,因此输出 3 。

数据范围: 1 \le n \le 500 \1≤n≤500
输入描述:
输入一行没有空格的字符串。

输出描述:
输出 输入字符串 中范围在(0~127,包括0和127)字符的种数。

示例1
输入:
abc

输出:
3

示例2
输入:
aaa

输出:
1

 */
public class HJ10字符不重复个数统计 {
    public static void main(String[] args) {
        //思路:map去重 再求不重复个数
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        char[] chars = str.toCharArray();
        int length = chars.length;
        //System.out.println(chars);
        Map<Integer,Character> map = new HashMap<>();
        for (int i=0; i<length ; i++){
            if (map.containsValue(chars[i])) continue;
            else map.put(i,chars[i]);
        }
        System.out.println(map.size());
    }
}
package HuaWei;
/*
Author:Sanro
Time:2022.05.15 14:01:01
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
输入一个整数,将这个整数以字符串的形式逆序输出
程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001


数据范围: 0 \le n \le 2^{30}-1 \0≤n≤2
30
 −1
输入描述:
输入一个int整数

输出描述:
将这个整数以字符串的形式逆序输出

示例1
输入:
1516000
复制
输出:
0006151
复制
示例2
输入:
0
复制
输出:
0

*/
import java.util.Scanner;

/*
描述
输入一个整数,将这个整数以字符串的形式逆序输出
程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001


数据范围: 0 \le n \le 2^{30}-1 \0≤n≤2
30
 −1
输入描述:
输入一个int整数

输出描述:
将这个整数以字符串的形式逆序输出

示例1
输入:
1516000

输出:
0006151

*/
public class HJ11数字颠倒 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int nextInt = sc.nextInt();
        char[] chars = String.valueOf(nextInt).toCharArray();
        //System.out.println(chars[0]);
        for (int i= 0 ;i<chars.length ; i++){
            System.out.print(chars[chars.length-i-1]);
        }
    }
}
package HuaWei;
/*
Author:Sanro
Time:2022.05.15 14:01:01
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
接受一个只包含小写字母的字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000)

输入描述:
输入一行,为一个只包含小写字母的字符串。

输出描述:
输出该字符串反转后的字符串。

示例1
输入:
abcd
复制
输出:
dcba

*/
import java.util.Scanner;

/*
* 描述
接受一个只包含小写字母的字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000)

输入描述:
输入一行,为一个只包含小写字母的字符串。

输出描述:
输出该字符串反转后的字符串。

示例1
输入:
abcd

输出:
dcba
*/
public class HJ12字符串颠倒 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String next = sc.nextLine();
        char[] chars = String.valueOf(next).toCharArray();
        //System.out.println(chars[0]);
        for (int i= 0 ;i<chars.length ; i++){
            System.out.print(chars[chars.length-i-1]);
        }
    }
}
package HuaWei;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/*
Author:Sanro
Time: 2022.05.14 14:49:22
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:HJ13 句子倒序
描述
将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I”
所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符
数据范围:输入的字符串长度满足 1 \le n \le 1000 \1≤n≤1000
注意本题有多组输入

输入描述:
输入一个英文语句,每个单词用空格隔开。保证输入只包含空格和字母。

输出描述:
得到逆序的句子

示例1
输入:
I am a boy

输出:
boy a am I

*/
public class HJ13英文句子颠倒 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //接收的字符串后面再额外不一个空格,方便后面判断
        String str = sc.nextLine()+" ";
        char[] chars = str.toCharArray();
        //以空格为界限,把数字内容放入map中,再倒序输出
        Map<Integer,String> map = new HashMap<>();
        String s ="";
        System.out.println(s.length());
        int count =0;
        for (int i = 0; i < chars.length ; i++) {
            if (chars[i]==' '){
                count++;
                map.put(count,s);
                System.out.println(map.values());
                s="";
            }
            else{ s=s+chars[i];}
        }
        for (int i = 0 ; i<count ; i++){
            System.out.print(map.get(count-i)+" ");
        }
    }
}
package HuaWei;
import java.util.Arrays;
import java.util.Scanner;

/*
Author:Sanro
Time:2022.05.14 16:22:50
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
给定 n 个字符串,请对 n 个字符串按照字典序排列。

数据范围: 1 \le n \le 1000 \1≤n≤1000  ,字符串长度满足 1 \le len \le 100 \1≤len≤100
输入描述:
输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。
输出描述:
数据输出n行,输出结果为按照字典序排列的字符串。
示例1
输入:
9
cap
to
cat
card
two
too
up
boat
boot

输出:
boat
boot
cap
card
cat
to
too
two
up

*/
public class HJ14字符串排序 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String[] strs = new String[n];
        for (int i = 0; i < n; i++) {
            //strs[i] = sc.nextLine();
            //这是因为之前输入一个nextInt后,输入的回车会被nextLine给接受,所以排序会少最后输入的字符串。
            //更改方案:可以将nextLine改为next,后者不接受空格回车:
            strs[i] = sc.next();
        }
        Arrays.sort(strs);
        for (String s : strs) {
            System.out.println(s);
        }
    }
}
package HuaWei;
/*
Author:Sanro
Time:2022.05.15 14:01:01
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
输入一个 int 型的正整数,计算出该 int 型数据在内存中存储时 1 的个数。

数据范围:保证在 32 位整型数字范围内
输入描述:
 输入一个整数(int类型)

输出描述:
 这个数转换成2进制后,输出1的个数

示例1
输入:
5
输出:
2

示例2
输入:
0
输出:
0

*/

import java.util.*;
import java.io.*;
/*
位移是我的知识短板,下面补齐知识不足
左移运算符 <<
右移运算符 >>
无符号左移运算符 <<<
无符号右移运算符 >>>
1100 1101 (205)
左移一位 0001 1001 1010 (410) 左边加一位1
右移一位 0000 0110 0110 (102) 右边减一位

无符号右移运算符>>>和右移运算符>>是一样的,
只不过右移时左边是补上符号位(负数补1整数补0),
而无符号右移运算符是补上0,
也就是说,对于正数移位来说等同于:>>,
负数通过此移位运算符能移位成正数。
*/
public class HJ15二进制数字特定个数_位移 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt(); //假如输入1010 0011
        int n = 0; //统计个数
        for (int i = 0; i < 32; i++) {  //32确定二进制不超过32位
            if ((num&1)==1) n++;        //末位与1进行与运算 同1为1其他为零
            num=num>>>1;                //无符号右移一位 比较数据的第二位
        }
        System.out.println(n);
    }
}
package HuaWei;
/*
Author:Sanro
Time:2022.05.15 14:47:54
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:
主件	附件
电脑	打印机,扫描仪
书柜	图书
书桌	台灯,文具
工作椅	无
如果要买归类为附件的物品,必须先买该附件所属的主件,且每件物品只能购买一次。
每个主件可以有 0 个、 1 个或 2 个附件。附件不再有从属于自己的附件。
王强查到了每件物品的价格(都是 10 元的整数倍),而他只有 N 元的预算。除此之外,他给每件物品规定了一个重要度,用整数 1 ~ 5 表示。他希望在花费不超过 N 元的前提下,使自己的满意度达到最大。
满意度是指所购买的每件物品的价格与重要度的乘积的总和,假设设第ii件物品的价格为v[i]v[i],重要度为w[i]w[i],共选中了kk件物品,编号依次为j_1,j_2,...,j_kj
请你帮助王强计算可获得的最大的满意度。


输入描述:
输入的第 1 行,为两个正整数N,m,用一个空格隔开:

(其中 N ( N<32000 )表示总钱数, m (m <60 )为可购买的物品的个数。)

从第 2 行到第 m+1 行,第 j 行给出了编号为 j-1 的物品的基本数据,每行有 3 个非负整数 v p q


(其中 v 表示该物品的价格( v<10000 ), p 表示该物品的重要度( 1 ~ 5 ), q 表示该物品是主件还是附件。如果 q=0 ,表示该物品为主件,如果 q>0 ,表示该物品为附件, q 是所属主件的编号)




输出描述:
 输出一个正整数,为张强可以获得的最大的满意度。
示例1
输入:
1000 5
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0
复制
输出:
2200
复制
示例2
输入:
50 5
20 3 5
20 3 5
10 3 0
10 2 0
10 1 0
复制
输出:
130
复制
说明:
由第1行可知总钱数N为50以及希望购买的物品个数m为5;
第2和第3行的q为5,说明它们都是编号为5的物品的附件;
第4~6行的q都为0,说明它们都是主件,它们的编号依次为3~5;
所以物品的价格与重要度乘积的总和的最大值为10*1+20*3+20*3=130
*/

import java.util.*;
import java.io.*;
/*

1、如果只包含主件,则是经典的01背包问题
2、现在加了附件,则最大值有四种情况:主件、主件+附件1、主件+附件2、主件+附件1+附件2
第一步:记录原始数据
记录每个主件以及其附件的关系,并记录其 价格 * 重要度
第二步:遍历主件
记录主件在四种情况下的最大值

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int money = in.nextInt()/10;//钱数是10的倍数,除以10,降低时间和空间复杂度
            int num = in.nextInt();
            //读取输入,区分主件,附件
            int[][] price = new int[num + 1][3];//记录主件和附件的价格
            int[][] pPlusImportant = new int[num + 1][3];//记录主件和附件的价格 * 重要度
            for(int i=1;i<=num;i++){
                int v = in.nextInt()/10;
                int p = in.nextInt();
                int q = in.nextInt();
                int im = v * p;
                if(q==0){
                    price[i][0] = v;//第一列是主件价格,第二列是附件1的价格,第三列附件2的价格
                    pPlusImportant[i][0] = im;
                }else{
                    if(price[q][1]==0){
                        price[q][1] = v;//主件q的附件1的价格
                        pPlusImportant[q][1] = im;
                    }else{
                        price[q][2] = v;//主件q的附件2的价格
                        pPlusImportant[q][2] = im;
                    }
                }
            }
            int[] dp = new int[money + 1];//背包问题,带附加条件
            for(int i=1;i<=num;i++){
                if(price[i][0] == 0){
                    continue;//主件为空,则跳过
                }
                for(int j=money;j>=price[i][0];j--){
                    int a = price[i][0];//主件
                    int a1 = pPlusImportant[i][0];
                    int b = price[i][1];//附件1
                    int b1 = pPlusImportant[i][1];
                    int c = price[i][2];//附件2
                    int c1 = pPlusImportant[i][2];
                    if(j>=a){
                        dp[j] = Math.max(dp[j],dp[j-a] + a1);
                    }
                    if(j>=a+b){
                        dp[j] = Math.max(dp[j],dp[j-a-b] + a1 + b1);
                    }
                    if(j>=a+c){
                        dp[j] = Math.max(dp[j],dp[j-a-c] + a1 + c1);
                    }
                    if(j>=a+b+c){
                        dp[j] = Math.max(dp[j],dp[j-a-b-c] + a1 + b1 + c1);
                    }
                }
            }
            System.out.println(dp[money] * 10);//开始的时候总钱数除10,输出的时候*10
        }
    }
}
*/
public class HJ16购物单_动态规划$ {
    //1、如果只包含主件,则是经典的01背包问题
    //2、现在加了附件,则最大值有四种情况:主件、主件+附件1、主件+附件2、主件+附件1+附件2
    //第一步:记录原始数据
    //记录每个主件以及其附件的关系,并记录其 价格 * 重要度
    //第二步:遍历主件
    //记录主件在四种情况下的最大值
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        String[] strs = s.split(" ");
        int m = Integer.parseInt(strs[0]); //钱数
        int n = Integer.parseInt(strs[1]);//件数
        for (int i = 0; i < n; i++) {
            String wp = sc.nextLine();
            String[] wp_strs = wp.split(" ");
            System.out.println(wp_strs[0]+":"+wp_strs[1]+":"+wp_strs[2]);
        }
    }
}
package HuaWei;
/*
Author:Sanro
Time:2022.05.16 13:27:59
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。
从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。
输入:
合法坐标为A(或者D或者W或者S) + 数字(两位以内)
坐标之间以;分隔。
非法坐标点需要进行丢弃。如AA10;  A1A;  $%$;  YAD; 等。
下面是一个简单的例子 如:

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)

数据范围:每组输入的字符串长度满足 1\le n \le 10000 \1≤n≤10000  ,
坐标保证满足 -2^{31} \le x,y \le 2^{31}-1 \−2
31≤x,y≤2 31-1  ,且数字部分仅含正数

输入描述:
一行字符串

输出描述:
最终坐标,以逗号分隔

示例1
输入:
A10;S20;W10;D30;X;A1A;B10A11;;A10;

输出:
10,-10

示例2
输入:
ABC;AKL;DA1;

输出:
0,0

*/

import java.util.*;
import java.io.*;
import java.util.*;
import java.io.*;

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

//public class HJ17坐标移动 {
//    public static void main(String[] args) {
//        Scanner sc = new Scanner(System.in);
//        String str = sc.next();
//
//    }
//
//    public static void xyz (String[] strs ){
//        String[] str = strs.split(";");
//        System.out.println(strs.length);
//            Integer x = 0,y=0;
//            char a = 'A',d='B',w='W',s='S';
//            for (int i = 0; i < strs.length; i++) {
//                System.out.println(strs[i]);
//                char[] chars = String.valueOf(strs[i]).toCharArray();
//                int WASD = Integer.parseInt(String.valueOf(chars[1])) * 10
//                        + Integer.parseInt(String.valueOf(chars[2]));
//                if (chars[0] == a) {
//                    x = x - WASD;
//                } else if (chars[0] == d) {
//                    x = x + WASD;
//                } else if (chars[0] == w) {
//                    y = y + WASD;
//                } else if (chars[0] == s) {
//                    y = y - WASD;
//                } else ;
//                System.out.println(WASD);
//            }
//            System.out.println(x+","+y);
//        }
//
//}


//输入:
//A10;S20;W10;D30;A10
//输出:
//10,-10
package HuaWei;
/*
Author:Sanro
Time:2022.05.16 15:51:17
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
请解析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的个数,之间以空格隔开。

示例1
输入:
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
示例2
输入:
0.201.56.50~255.255.111.255
127.201.56.50~255.255.111.255

输出:
0 0 0 0 0 0 0

说明:
类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类,也不属于不合法ip地址,计数时请忽略
*/

import java.util.*;
import java.io.*;

import java.util.*;
/*
结合前面几位大佬的题解,整出一个Java版.这里有个大坑,
若是ip是0或者127开头的直接忽略,即使子网掩码是非法的,
也不能将此算到error里去。 具体实现

查看ip第一段是否为“0”或“127”,若是忽略;
判断子网掩码是否合法,如果满足下列条件之一即为非法掩码
数字段数不为4
在二进制下,不满足前面连续是1,然后全是0
在二进制下,全为0或全为1
判断IP地址是否合法,如果满足下列条件之一即为非法地址
数字段数不为4,比如存在空段,即【192..1.0】这种;
某个段的数字大于255
判断ip是否是ABCDE类地址,若是对应类加一。

所有的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是否私有地址。
私网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
*/
public class HJ18识别IP和掩码$ {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int aNum = 0;
        int bNum = 0;
        int cNum = 0;
        int dNum = 0;
        int eNum = 0;
        int errNum = 0;
        int pNum = 0;
        while (sc.hasNextLine()) {
            String str = sc.nextLine();
            String[] strArr = str.split("~");
            int ipFirst = getIpSeg(strArr[0], 0);
            if (ipFirst == 0 || ipFirst == 127) {
                continue;
            }
            if (maskIsInvaild(strArr[1])) {
                errNum++;
                continue;
            }
            if (ipIsInvaild(strArr[0])) {
                errNum++;
                continue;
            }
            if (ipFirst >= 1 && ipFirst <= 126) {
                aNum++;
            }
            if (ipFirst >= 128 && ipFirst <= 191) {
                bNum++;
            }
            if (ipFirst >= 192 && ipFirst <= 223) {
                cNum++;
            }
            if (ipFirst >= 224 && ipFirst <= 239) {
                dNum++;
            }
            if (ipFirst >= 240 && ipFirst <= 255) {
                eNum++;
            }
            int ipSecond = getIpSeg(strArr[0], 1);
            if (ipFirst == 10 || (ipFirst == 172 && ipSecond >= 16 && ipSecond <=31) || (ipFirst == 192 && ipSecond == 168)) {
                pNum++;
            }
        }
        System.out.println(aNum + " " + bNum + " " + cNum + " " + dNum + " " + eNum + " " + errNum + " " + pNum);
    }

    public static boolean maskIsInvaild(String mask) {
        String[] maskArr = mask.split("\\.");
        if (maskArr.length != 4) {
            return true;
        }
        String maskBinary = toBinary(maskArr[0]) + toBinary(maskArr[1]) + toBinary(maskArr[2]) + toBinary(maskArr[3]);
        if (!maskBinary.matches("[1]{1,}[0]{1,}")) {
            return true;
        }
        return false;
    }

    public static String toBinary(String num) {
        String numBinary = Integer.toBinaryString(Integer.valueOf(num));
        while (numBinary.length() < 8) {
            numBinary = "0" + numBinary;
        }
        return numBinary;
    }

    public static boolean ipIsInvaild(String ip) {
        String[] ipArr = ip.split("\\.");
        if (ipArr.length != 4) {
            return true;
        }
        if (Integer.valueOf(ipArr[0]) > 255 || Integer.valueOf(ipArr[1]) > 255 || Integer.valueOf(ipArr[2]) > 255 || Integer.valueOf(ipArr[3]) > 255) {
            return true;
        }
        return false;
    }

    public static int getIpSeg(String ip, int index) {
        String[] ipArr = ip.split("\\.");
        return Integer.valueOf(ipArr[index]);
    }
}

package HuaWei;
/*
Author:Sanro
Time:2022.05.16 18:19:23
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。


处理:


1、 记录最多8条错误记录,循环记录,最后只用输出最后出现的八条错误记录。对相同的错误记录只记录一条,但是错误计数增加。最后一个斜杠后面的带后缀名的部分(保留最后16位)和行号完全匹配的记录才做算是“相同”的错误记录。
2、 超过16个字符的文件名称,只记录文件的最后有效16个字符;
3、 输入的文件可能带路径,记录文件名称不能带路径。也就是说,哪怕不同路径下的文件,如果它们的名字的后16个字符相同,也被视为相同的错误记录
4、循环记录时,只以第一次出现的顺序为准,后面重复的不会更新它的出现时间,仍以第一次为准

数据范围:错误记录数量满足 1 \le n \le 100 \1≤n≤100  ,每条记录长度满足 1 \le len \le 100 \1≤len≤100
输入描述:
每组只包含一个测试用例。一个测试用例包含一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。

输出描述:
将所有的记录统计并将结果输出,格式:文件名 代码行数 数目,一个空格隔开,如:

示例1
输入:
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.*;
import java.io.*;

public class HJ19错误记录$ {
    public static void main(String[] args) throws IOException{
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        Map<String,Integer> map = new LinkedHashMap();
        String tstr = null;
        while((tstr = bf.readLine()) != null && !tstr.equals("")){
            String[] str = tstr.split("\\s+");
            String fname=str[0].substring(str[0].lastIndexOf("\\") + 1);
            fname = fname.substring(Math.max(fname.length()-16 ,0))+" "+str[1];
            Integer tmp = map.get(fname);
            if(tmp == null)
                map.put(fname,1);
            else
                map.put(fname, tmp+1);
        }
        int count = 0;
        for(Map.Entry<String,Integer> it : map.entrySet()){
            if(map.size() - count <= 8)
                System.out.println(it.getKey()+" "+it.getValue());
            count++;
        }
    }
}
package HuaWei;
/*
Author:Sanro
Time:2022.05.17 20:03:40
Blog:https://sanlangcode.com
Email:sanlangcode@163.com
Desc:
描述
密码要求:
1.长度超过8位
2.包括大小写字母.数字.其它符号,以上四种至少三种
3.不能有长度大于2的包含公共元素的子串重复 (注:其他符号不含空格或换行)

数据范围:输入的字符串长度满足 1≤n≤100
输入描述:
一组字符串。

输出描述:
如果符合要求输出:OK,否则输出NG

示例1
输入:
021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000

输出:
OK
NG
NG
OK

*/

import java.util.*;
import java.io.*;

public class HJ20密码合格验证 {
    //依次判断密码的条件。
    // 1:长度判断。
    // 2:四个种类的字符判断。用一个abcd四个变量代表四个条件来判断即可。
    // 3:重复判断,这个可以利用循环截取3个字符组成字符串s,
    // 使剩余字符与s模式匹配,如果匹配到了那说明重复,不合格。
    /*
    示例1
输入:
021Abc9000
021Abc9Abc1
021ABC9000
021$bc9000

输出:
OK
NG
NG
OK
    */
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) { //作用输入直到回车
            String pwds = in.nextLine();
            char[] pwd = pwds.toCharArray();
            int a=0,b=0,c=0,d=0 ;
            if(pwd.length>=8){
                for(int i =0;i<pwd.length;++i){
                    if(pwd[i]>='0'&&pwd[i]<='9')a=1;
                    else if(pwd[i]>='A'&&pwd[i]<='Z') b=1;
                    else if(pwd[i]>='a'&&pwd[i]<='z') c=1;
                    else d=1;
                    if(a+b+c+d>=3)break;
                }
                if(a+b+c+d>=3){
                    boolean isvalid = true;
                    for(int i =0;i<pwds.length()-3;++i){
                        String s = pwds.substring(i,i+3);
                        String ssuffix = pwds.substring(i+3);
                        if( ssuffix.contains(s)){
                            System.out.println("NG");
                            isvalid = false;
                            break;
                        }
                    }
                    if(isvalid)
                        System.out.println("OK");
                    continue;
                }
                else {
                    System.out.println("NG");
                    continue;
                }
            }
            System.out.println("NG");
        }
    }

}