华为机试算法整理

1、HJ1  字符串最后一个单词的长度

计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)

package com.micheal;

import java.util.Scanner;

/**
 * 计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)
 * 输出最后一个字符串的长度
 */
public class HJ1 {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        String inputStr = s.nextLine();
        String[] strArr = inputStr.split(" ");
        int lastWordLength = strArr[strArr.length-1].length();
        System.out.println(lastWordLength);
    }
}

2、HJ2  计算某字符出现次数

写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中该字符的出现次数。(不区分大小写字母)

package com.micheal;

import java.util.Scanner;

/**
 * 写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中该字符的出现次数。(不区分大小写字母)
 * 数据范围:1≤n≤1000
 * 计算指定字符串出现的次数
 */
public class HJ2 {
    public static void main(String[] args) {
        Scanner s =new Scanner(System.in);
        String inputStr = s.nextLine();
        String character = s.nextLine();
        String replaceStr = inputStr.toUpperCase().replaceAll(character.toUpperCase(),"");
        System.out.println(inputStr.length()-replaceStr.length());
    }
}

3、HJ3   明明的随机数

明明生成了NN个1到500之间的随机整数。请你删去其中重复的数字,即相同的数字只保留一个,把其余相同的数去掉,然后再把这些数从小到大排序,按照排好的顺序输出。

package com.micheal;

import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeSet;

/**
 * 明明生成了NN个1到500之间的随机整数。请你删去其中重复的数字,即相同的数字只保留一个,把其余相同的数去掉,然后再把这些数从小到大排序,按照排好的顺序输出
 * 数据范围:1≤n≤1000,输入的数字大小满足1≤val≤500
 */
public class HJ3 {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        while(s.hasNext()){
            int num = s.nextInt();
            TreeSet set = new TreeSet();
            for (int i = 0; i < num; i++) {
                set.add(s.nextInt());
            }
            Iterator iterator = set.iterator();
            while (iterator.hasNext()){
                System.out.println(iterator.next());
            }
        }
    }
}

4、HJ4  字符串分隔

•连续输入字符串,请按长度为8拆分每个输入字符串并进行输出;

•长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。

package com.micheal;

import java.util.Scanner;

/**
 * •连续输入字符串,请按长度为8拆分每个输入字符串并进行输出;
 * •长度不是8整数倍的字符串请在后面补数字0,空字符串不处理。
 */
public class HJ4 {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        while(s.hasNextLine()){
            String str = s.nextLine();
            while(str.length()>8){
                System.out.println(str.substring(0,8));
                str = str.substring(8);
            }
            while (str.length()<8&&str.length()>0){
                str+="0";
            }
            System.out.println(str);
        }
    }
}

5、HJ5  进制转换

写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。

package com.micheal;

import java.util.Scanner;

/**
 * 写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。
 */
public class HJ5 {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        while(s.hasNextLine()){
            String str = s.nextLine();
            String result = str.substring(2,str.length());
            System.out.println(Integer.parseInt(result,16));
        }
    }
}

6、HJ6  质数因子

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

package com.micheal;

import java.util.Scanner;

/**
 * 功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )
 */
public class HJ6 {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        long num = s.nextLong();
        long k = (long)Math.sqrt(num);
        for(long i=2;i

7、HJ7  取近似值

写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于 0.5 ,向上取整;小于 0.5 ,则向下取整。

数据范围:保证输入的数字在 32 位浮点数范围内

package com.micheal;

import java.util.Scanner;

/**
 * 写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于 0.5 ,向上取整;小于 0.5 ,则向下取整。
 */
public class HJ7 {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        float num = s.nextFloat();
        System.out.println(Math.round(num));
    }
}

8、HJ8  合并表记录

数据表记录包含表索引index和数值value(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照index值升序进行输出。

package com.micheal;

import java.util.Scanner;
import java.util.TreeMap;

/**
 * 数据表记录包含表索引index和数值value(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照index值升序进行输出。
 */
public class HJ8 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        TreeMap map = new TreeMap<>();
        int num = sc.nextInt();
        for (int i = 0; i < num; i++) {
            int key = sc.nextInt();
            int value = sc.nextInt();
            map.put(key, map.getOrDefault(key, 0) + value);
        }
        for (Integer key : map.keySet()) {
            System.out.println(key + " " + map.get(key));
        }
    }
}

9、HJ9  提取不重复的整数

输入一个 int 型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。

保证输入的整数最后一位不是 0 。

package com.micheal;

import java.util.HashSet;
import java.util.Scanner;

/**
 * 输入一个 int 型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。
 * 保证输入的整数最后一位不是 0 。
 */
public class HJ9 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int num = sc.nextInt();
            HashSet set = new HashSet<>();
            while (num != 0){
                int temp = num%10;
                if(set.add(temp)){
                    System.out.print(temp);
                }
                num/=10;
            }
            System.out.println();
        }
    }
}

10、HJ10  字符个数统计

编写一个函数,计算字符串中含有的不同字符的个数。字符在 ASCII 码范围内( 0~127 ,包括 0 和 127 ),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次

例如,对于字符串 abaca 而言,有 a、b、c 三种不同的字符,因此输出 3 。

package com.micheal;

import java.util.HashSet;
import java.util.Scanner;

/**
 * 编写一个函数,计算字符串中含有的不同字符的个数。字符在 ASCII 码范围内( 0~127 ,包括 0 和 127 ),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次
 * 例如,对于字符串 abaca 而言,有 a、b、c 三种不同的字符,因此输出 3 。
 */
public class HJ10 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String charStr = sc.nextLine();
        HashSet set = new HashSet<>();
        for(int i =0;i

11、HJ11  数字颠倒

输入一个整数,将这个整数以字符串的形式逆序输出

程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001

package com.micheal;

import java.util.Scanner;

/**
 * 输入一个整数,将这个整数以字符串的形式逆序输出
 * 程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001
 */
public class HJ11 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        String numStr = String.valueOf(num);
        StringBuffer stringBuffer = new StringBuffer(numStr);
        System.out.println(stringBuffer.reverse());
    }
}

12、HJ12  字符串反转

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

package com.micheal;

import java.util.Scanner;

/**
 * 接受一个只包含小写字母的字符串,然后输出该字符串反转后的字符串。(字符串长度不超过1000)
 */
public class HJ12 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        StringBuffer stringBuffer = new StringBuffer(str);
        System.out.println(stringBuffer.reverse());
    }
}

13、HJ13  句子逆序

将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I”

所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符

package com.micheal;

import java.util.Scanner;

/**
 * 将一个英文语句以单词为单位逆序排放。例如“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();
        String[] split = str.split(" ");
        for(int i = split.length-1;i>=0;i--){
            System.out.print(split[i]+" ");
        }
    }
}

14、HJ14  字符串排序

给定 n 个字符串,请对 n 个字符串按照字典序排列。

package com.micheal;

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

/**
 * 给定 n 个字符串,请对 n 个字符串按照字典序排列。
 */
public class HJ14 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = Integer.valueOf(sc.nextLine());
        String[] arr = new String[num];
        for(int i =0;i

15、HJ15  求int型正整数在内存中存储时1的个数

输入一个 int 型的正整数,计算出该 int 型数据在内存中存储时 1 的个数。

package com.micheal;

import java.util.Scanner;

/**
 * 求int型正整数在内存中存储时1的个数
 */
public class HJ15 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        int n = 0;
        for(int i =0;i<32;i++){
            if((num&1)==1){
                n++;
            }
            num = num>>>1;
        }
        System.out.println(n);
    }
}

16、HJ16   购物单

王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:

package com.micheal;

import java.util.Scanner;

/**
 * 购物清单
 */
public class HJ16 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int m = sc.nextInt();
        int[][] dp = new int[m + 1][N + 1];
        int[][] pr = new int[m + 1][3];
        int[][] imp = new int[m + 1][3];
        for (int i = 1; i <= m; i++) {
            int v = sc.nextInt();
            int p = sc.nextInt();
            int q = sc.nextInt();
            if (q == 0) {
                pr[i][0] = v;
                imp[i][0] = p;
            } else {
                if (pr[q][1] == 0) {
                    pr[q][1] = v;
                    imp[q][1] = p;
                } else {
                    pr[q][2] = v;
                    imp[q][2] = p;
                }
            }
        }
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= N; j++) {
                if (pr[i][0] == 0) {
                    dp[i][j] = dp[i - 1][j];
                } else {
                    if (pr[i][0] > j) {
                        dp[i][j] = dp[i - 1][j];
                    } else {
                        dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - pr[i][0]] + pr[i][0] * imp[i][0]);
                        if (pr[i][0] + pr[i][1] <= j) {
                            dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - pr[i][0] - pr[i][1]] + pr[i][0] * imp[i][0] + pr[i][1] * imp[i][1]);
                        }
                        if (pr[i][0] + pr[i][2] <= j) {
                            dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - pr[i][0] - pr[i][2]] + pr[i][0] * imp[i][0] + pr[i][2] * imp[i][2]);
                        }
                        if (pr[i][0] + pr[i][1] + pr[i][2] <= j) {
                            dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - pr[i][0] - pr[i][1] - pr[i][2]] + pr[i][0] * imp[i][0] + pr[i][1] * imp[i][1] + pr[i][2] * imp[i][2]);
                        }
                    }
                }
            }
        }
        System.out.print(dp[m][N]);
    }
}

17、HJ17  坐标移动

开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。

package com.micheal;

import java.util.Scanner;

public class HJ17 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String inputStr = sc.nextLine();
        String[] in = inputStr.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);
    }
}

18、HJ18  识别有效的IP地址和掩码并进行分类统计

请解析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均为非法子网掩码)

package com.micheal;

import java.util.Scanner;

public class HJ18 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] ipAndMask = new String[2];
        String[] ipArr = new String[4];
        int A = 0,B = 0,C = 0,D =0,E = 0,errIpOrMask = 0,privateIp = 0;
        while (in.hasNextLine()) {
            ipAndMask = in.nextLine().split("\\~");
            if(ipAndMask[0].equals("end")){
                break;
            }
            ipArr = ipAndMask[0].split("\\.");
            if(ipArr[0].equals("0") || ipArr[0].equals("127")){
                continue;
            }
            if(!isValidMask(ipAndMask[1])){
                errIpOrMask++;
            }else{
                if(!isValidIp(ipAndMask[0])){
                    errIpOrMask++;
                }else{
                    if(Integer.parseInt(ipArr[0])>=1 && Integer.parseInt(ipArr[0])<=126){
                        if(Integer.parseInt(ipArr[0])==10){
                            privateIp++;
                            A++;
                        }else{
                            A++;
                        }
                    }
                    if(Integer.parseInt(ipArr[0])>=128 && Integer.parseInt(ipArr[0])<=191){
                        if(Integer.parseInt(ipArr[0])==172 && (Integer.parseInt(ipArr[1]) >=16 && Integer.parseInt(ipArr[1])<=31)){
                            privateIp++;
                            B++;
                        }else{
                            B++;
                        }
                    }
                    if(Integer.parseInt(ipArr[0])>=192 && Integer.parseInt(ipArr[0])<=223){
                        if(Integer.parseInt(ipArr[0])==192 && Integer.parseInt(ipArr[1]) ==168){
                            privateIp++;
                            C++;
                        }else{
                            C++;
                        }
                    }
                }
                if(Integer.parseInt(ipArr[0])>=224 && Integer.parseInt(ipArr[0])<=239){
                    D++;
                }
                if(Integer.parseInt(ipArr[0])>=240 && Integer.parseInt(ipArr[0])<=255){
                    E++;
                }
            }
        }
        System.out.println(A + " " + B + " " + C + " " + D + " " + E + " " + errIpOrMask + " " + privateIp);
    }
    public static boolean isValidMask(String mask){
        if(!isValidIp(mask)){
            return false;
        }
        String[] maskTable = mask.split("\\.");
        StringBuilder sb = new StringBuilder();
        for(int i=0;i 255){
                return false;
            }
        }
        return true;
    }
}

19、HJ19  简单错误记录

开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。

package com.micheal;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedHashMap;
import java.util.Map;

public class HJ19 {
    public static void main(String[] args) throws IOException {
            BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
            Map 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 it : map.entrySet()){
                if(map.size() - count <= 8)
                    System.out.println(it.getKey()+" "+it.getValue());
                count++;
            }
    }
}

20、HJ20  密码验证合格程序

密码要求:

1.长度超过8位

2.包括大小写字母.数字.其它符号,以上四种至少三种

3.不能有长度大于2的不含公共元素的子串重复 (注:其他符号不含空格或换行)

package com.micheal;

import java.util.Scanner;
import java.util.regex.Pattern;

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

21、HJ21  简单密码

现在有一种密码变换算法。

九键手机键盘上的数字与字母的对应: 1--1, abc--2, def--3, ghi--4, jkl--5, mno--6, pqrs--7, tuv--8 wxyz--9, 0--0,把密码中出现的小写字母都变成九键键盘对应的数字,如:a 变成 2,x 变成 9.

而密码中出现的大写字母则变成小写之后往后移一位,如:X ,先变成小写,再往后移一位,变成了 y ,例外:Z 往后移是 a 。

数字和其它的符号都不做变换。

package com.micheal;

import java.util.Scanner;

public class HJ21 {
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        while(in.hasNext()){
            String str=in.nextLine();
            char c[]=str.toCharArray();
            for(int i=0;i='A'&&c[i]<='Z'){
                    if(c[i]+32!='z')
                        c[i]+=32+1;
                    else
                        c[i]='a';
                }
                else if(c[i]>='a'&&c[i]<='r')
                    c[i]=(char) ((c[i]-'a')/3+2+'0');
                else if(c[i]=='s')
                    c[i]='7';
                else if(c[i]>='t'&&c[i]<='v')
                    c[i]='8';
                else if(c[i]>='w'&&c[i]<='z')
                    c[i]='9';

                System.out.print(c[i]);
            }
            System.out.println();
        }
    }

}

22、HJ22  汽水瓶

某商店规定:三个空汽水瓶可以换一瓶汽水,允许向老板借空汽水瓶(但是必须要归还)。

小张手上有n个空汽水瓶,她想知道自己最多可以喝到多少瓶汽水。

package com.micheal;

import java.util.Scanner;

public class HJ22 {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextInt()){
            int bottle = sc.nextInt();
            if(bottle==0){
                break;
            }
            System.out.println(bottle/2);
        }
    }
}

23、HJ23  删除字符串中出现次数最少的字符

实现删除字符串中出现次数最少的字符,若出现次数最少的字符有多个,则把出现次数最少的字符都删除。输出删除这些单词后的字符串,字符串中其它字符保持原来的顺序。

package com.micheal;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Scanner;

public class HJ23 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String s = scanner.nextLine();
            char[] chars = s.toCharArray();
            HashMap map = new HashMap<>();
            for (char aChar : chars) {
                map.put(aChar, (map.getOrDefault(aChar, 0) + 1));
            }
            Collection values = map.values();
            Integer min = Collections.min(values);
            for (Character character : map.keySet()) {
                if (map.get(character) == min){
                    s = s.replaceAll(String.valueOf(character), "");
                }
            }
            System.out.println(s);
        }
    }
}

24、HJ24  合唱队

N 位同学站成一排,音乐老师要请最少的同学出列,使得剩下的 K 位同学排成合唱队形。

设KK位同学从左到右依次编号为 1,2…,K ,他们的身高分别为T_1,T_2,…,T_KT1​,T2​,…,TK​ ,若存在i(1\leq i\leq K)i(1≤i≤K) 使得T_1T_{i+1}>......>T_KTi​>Ti+1​>......>TK​,则称这KK名同学排成了合唱队形。

通俗来说,能找到一个同学,他的两边的同学身高都依次严格降低的队形就是合唱队形。

例子: 

123 124 125 123 121 是一个合唱队形

123 123 124 122不是合唱队形,因为前两名同学身高相等,不符合要求

123 122 121 122不是合唱队形,因为找不到一个同学,他的两侧同学身高递减。

你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

注意:不允许改变队列元素的先后顺序  不要求最高同学左右人数必须相等

package com.micheal;

import java.util.Scanner;

public class HJ24 {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextInt()){
            int n = sc.nextInt();
            int[] arr = new int[n];
            int[] arrL = new int[n];
            int[] arrR = new int[n];
            for(int i = 0; i < n; ++i){
                arr[i] = sc.nextInt();
            }
            for(int i = 0; i < n; ++i){
                arrL[i] = 0;
                for(int j = 0; j < i; ++j){
                    if(arr[i] > arr[j]){
                        arrL[i] = Math.max(arrL[j] + 1, arrL[i]);
                    }
                }
            }
            for(int i = n - 1; i >= 0; --i){
                arrR[i] = 0;
                for(int j = n - 1; j > i; --j){
                    if(arr[i] > arr[j]){
                        arrR[i] = Math.max(arrR[j] + 1, arrR[i]);
                    }
                }
            }
            int maxValue = 0;
            for(int i = 0; i < n; ++i){
                maxValue = Math.max(maxValue, arrR[i] + arrL[i] + 1);
            }
            System.out.println(n - maxValue);
        }
    }
}

25、HJ25  数据分类处理

信息社会,有海量的数据需要分析处理,比如公安局分析身份证号码、 QQ 用户、手机号码、银行帐号等信息及活动记录。

采集输入大数据和分类规则,通过大数据分类处理程序,将大数据分类输出。

package com.micheal;

import java.util.*;

public class HJ25 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int num = sc.nextInt();
            String[] array = new String[num];
            for (int i =0; i set = new TreeSet<>();
            for (int i =0; i map = new TreeMap<>();
                for (String str : array) {
                    if (str.contains(String.valueOf(i))){
                        map.put(j, str);
                    }
                    j++;
                }
                if (!map.isEmpty()) {
                    if (count > 0) {
                        result.append(" ");
                    }
                    result.append(i).append(" ").append(map.size());
                    count +=2;
                    for (Map.Entry entry : map.entrySet()) {
                        count+=2;
                        result.append(" ").append(entry.getKey()).append(" ").append(entry.getValue());
                    };
                }
            }
            if (count > 0) {
                StringBuilder result2 = new StringBuilder();
                result2.append(count).append(" ").append(result);
                System.out.println(result2);
            }
        }
    }
}

26、HJ26  字符串排序

编写一个程序,将输入字符串中的字符按如下规则排序。

规则 1 :英文字母从 A 到 Z 排列,不区分大小写。

如,输入: Type 输出: epTy

规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。

如,输入: BabA 输出: aABb

规则 3 :非英文字母的其它字符保持原来的位置。
 

如,输入: By?e 输出: Be?y

package com.micheal;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;

public class HJ26 {
    public static String sort(String str) {
        List letters = new ArrayList<>();
        for (char ch : str.toCharArray()) {
            if (Character.isLetter(ch)) {
                letters.add(ch);
            }
        }
        letters.sort(new Comparator() {
            public int compare(Character o1, Character o2) {
                return Character.toLowerCase(o1) - Character.toLowerCase(o2);
            }
        });
        StringBuilder result = new StringBuilder();
        for (int i = 0, j = 0; i < str.length(); i++) {
            if (Character.isLetter(str.charAt(i))) {
                result.append(letters.get(j++));
            }
            else {
                result.append(str.charAt(i));
            }
        }
        return result.toString();
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            String str = in.nextLine();
            String res = sort(str);
            System.out.println(res);
        }
    }
}

27、HJ27  查找兄弟单词

定义一个单词的“兄弟单词”为:交换该单词字母顺序(注:可以交换任意次),而不添加、删除、修改原有的字母就能生成的单词。

兄弟单词要求和原来的单词不同。例如: ab 和 ba 是兄弟单词。 ab 和 ab 则不是兄弟单词。

现在给定你 n 个单词,另外再给你一个单词 x ,让你寻找 x 的兄弟单词里,按字典序排列后的第 k 个单词是什么?

注意:字典中可能有重复单词。

package com.micheal;

import java.util.*;

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

    public static boolean isBrother(String x, String y) {
        if (x.length() != y.length() || y.equals(x)) {
            return false;
        }
        char[] s = x.toCharArray();
        char[] j = y.toCharArray();
        Arrays.sort(s);
        Arrays.sort(j);
        return new String(s).equals(new String(j));
    }
}

28、HJ28  素数伴侣

题目描述
若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的 N ( N 为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。

package com.micheal;

import java.util.ArrayList;
import java.util.Scanner;

public class HJ28 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            int[] arr = new int[n];
            ArrayList odds = new ArrayList<>();
            ArrayList evens = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                arr[i] = sc.nextInt();
                if (arr[i] % 2 == 1) {
                    odds.add(arr[i]);
                }
                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[] v = new boolean[evens.size()];
                if (find(odds.get(j), matcheven, evens, v)) {
                    count++;
                }
            }
            System.out.println(count);
        }
    }

    private static boolean find(int x, int[] matcheven, ArrayList evens, boolean[] v) {
        for (int i = 0; i < evens.size(); i++) {
            if (isPrime(x + evens.get(i)) && v[i] == false) {
                v[i] = true;
                if (matcheven[i] == 0 || find(matcheven[i], matcheven, evens, v)) {
                    matcheven[i] = x;
                    return true;
                }
            }
        }
        return false;
    }

    private static boolean isPrime(int x) {
        if (x == 1) return false;
        for (int i = 2; i <= (int) Math.sqrt(x); i++) {
            if (x % i == 0) {
                return false;
            }
        }
        return true;
    }
}

29、HJ29  字符串加解密

对输入的字符串进行加解密,并输出。

加密方法为:

当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母a时则替换为B;字母Z时则替换为a;

当内容是数字时则把该数字加1,如0替换1,1替换2,9替换0;

其他字符不做变化。

解密方法为加密的逆过程。

数据范围:输入的两个字符串长度满足 1 \le n \le 1000 \1≤n≤1000  ,保证输入的字符串都是只由大小写字母或者数字组成

package com.micheal;

import java.util.Scanner;

public class HJ29 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            System.out.println(encode(in.nextLine()));
            System.out.println(decode(in.nextLine()));
        }
    }

    private static String encode(String code) {
        char[] t = code.toCharArray();
        for (int i = 0; i < t.length; i++) {
            if (t[i] >= 'a' && t[i] < 'z')
                t[i] = (char) (t[i] - 'a' + 'A' + 1);
            else if (t[i] == 'z')
                t[i] = 'A';
            else if (t[i] >= 'A' && t[i] < 'Z')
                t[i] = (char) (t[i] - 'A' + 'a' + 1);
            else if (t[i] == 'Z')
                t[i] = 'a';
            else if (t[i] >= '0' && t[i] < '9')
                t[i] = (char) (t[i] + 1);
            else if (t[i] == '9')
                t[i] = '0';
        }
        return String.valueOf(t);
    }

    private static String decode(String password) {
        char[] t = password.toCharArray();
        for (int i = 0; i < t.length; i++) {
            if (t[i] > 'a' && t[i] <= 'z')
                t[i] = (char) (t[i] - 'a' + 'A' - 1);
            else if (t[i] == 'a')
                t[i] = 'Z';
            else if (t[i] > 'A' && t[i] <= 'Z')
                t[i] = (char) (t[i] - 'A' + 'a' - 1);
            else if (t[i] == 'A')
                t[i] = 'z';
            else if (t[i] > '0' && t[i] <= '9')
                t[i] = (char) (t[i] - 1);
            else if (t[i] == '0')
                t[i] = '9';
        }
        return String.valueOf(t);
    }
}

30、HJ30  字符串合并处理

按照指定规则对输入的字符串进行处理。

详细描述:

第一步:将输入的两个字符串str1和str2进行前后合并。如给定字符串 "dec" 和字符串 "fab" , 合并后生成的字符串为 "decfab"

第二步:对合并后的字符串进行排序,要求为:下标为奇数的字符和下标为偶数的字符分别从小到大排序。这里的下标的意思是字符在字符串中的位置。注意排序后在新串中仍需要保持原来的奇偶性。例如刚刚得到的字符串“decfab”,分别对下标为偶数的字符'd'、'c'、'a'和下标为奇数的字符'e'、'f'、'b'进行排序(生成 'a'、'c'、'd' 和 'b' 、'e' 、'f'),再依次分别放回原串中的偶数位和奇数位,新字符串变为“abcedf”

第三步:对排序后的字符串中的'0'~'9'、'A'~'F'和'a'~'f'字符,需要进行转换操作。

转换规则如下:

对以上需要进行转换的字符所代表的十六进制用二进制表示并倒序,然后再转换成对应的十六进制大写字符(注:字符 a~f 的十六进制对应十进制的10~15,大写同理)。

如字符 '4',其二进制为 0100 ,则翻转后为 0010 ,也就是 2 。转换后的字符为 '2'。

如字符 ‘7’,其二进制为 0111 ,则翻转后为 1110 ,对应的十进制是14,转换为十六进制的大写字母为 'E'。

如字符 'C',代表的十进制是 12 ,其二进制为 1100 ,则翻转后为 0011,也就是3。转换后的字符是 '3'。

根据这个转换规则,由第二步生成的字符串 “abcedf” 转换后会生成字符串 "5D37BF"。

package com.micheal;

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

public class HJ30 {
    public static void main(String[] str) {
        processStr();
    }

    public static void processStr() {
        Map map = new HashMap() {{
            put('0', '0');
            put('1', '8');
            put('2', '4');
            put('3', 'C');
            put('4', '2');
            put('5', 'A');
            put('6', '6');
            put('7', 'E');
            put('8', '1');
            put('9', '9');
            put('a', '5');
            put('b', 'D');
            put('c', '3');
            put('d', 'B');
            put('e', '7');
            put('f', 'F');
            put('A', '5');
            put('B', 'D');
            put('C', '3');
            put('D', 'B');
            put('E', '7');
            put('F', 'F');
        }};
        Scanner scanner = new Scanner(System.in);
        String s = "";
        while (scanner.hasNext()) {
            String s1 = scanner.next();
            String s2 = scanner.next();
            char[] ch = (s1 + s2).toCharArray();
            char[] r1 = new char[ch.length / 2];
            char[] r2 = new char[ch.length - ch.length / 2];
            for (int i = 0, j = 0, k = 0; i < ch.length; i++) {
                if (i % 2 == 0) {
                    r2[j] = ch[i];
                    j++;
                } else {
                    r1[k] = ch[i];
                    k++;
                }
            }
            Arrays.sort(r1);
            Arrays.sort(r2);
            for (int i = 0, j = 0, k = 0; i < ch.length; i++) {
                if (i % 2 == 0) {
                    ch[i] = map.getOrDefault(r2[j], r2[j]);
                    j++;
                } else {
                    ch[i] = map.getOrDefault(r1[k], r1[k]);
                    k++;
                }
            }
            s = new String(ch);
            System.out.println(s);
        }
    }
}

31、HJ31  单词倒排

对字符串中的所有单词进行倒排。

说明:

1、构成单词的字符只有26个大写或小写英文字母;

2、非构成单词的字符均视为单词间隔符;

3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;

4、每个单词最长20个字母;

package com.micheal;

import java.util.Scanner;

public class HJ31 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String test = sc.nextLine();
        char[] ch = test.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < ch.length; i++) {
            if (Character.isLetter(ch[i])) {
                sb.append(ch[i]);
            } else {
                sb.append(" ");
            }
        }
        String[] arr = sb.toString().split(" ");
        for (int i = arr.length - 1; i >= 0; i--) {
            System.out.print(arr[i] + " ");
        }
    }
}

32、HJ32  密码截取

Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?

package com.micheal;

import java.util.Scanner;

public class HJ32 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        System.out.println(solution(s));
    }

    private static int solution(String s) {
        int res = 0;
        for (int i = 0; i < s.length(); i++) {
            int len1 = longest(s, i, i);
            int len2 = longest(s, i, i + 1);
            res = Math.max(res, len1 > len2 ? len1 : len2);
        }
        return res;
    }

    private static int longest(String s, int l, int r) {
        while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) {
            l--;
            r++;
        }
        return r - l - 1;
    }
}

33、HJ33  整数与IP地址间的转换

原理:ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成
一个长整数。
举例:一个ip地址为10.0.3.193
每段数字             相对应的二进制数
10                   00001010
0                    00000000
3                    00000011
193                  11000001

组合起来即为:00001010 00000000 00000011 11000001,转换为10进制数就是:167773121,即该IP地址转换后的数字就是它了。

数据范围:保证输入的是合法的 IP 序列

package com.micheal;

import java.util.Scanner;

public class HJ33 {
    private static final int N = 4;

    public static String convert(String str) {
        if (str.contains(".")) {
            String[] fields = str.split("\\.");
            long result = 0;
            for (int i = 0; i < N; i++) {
                result = result * 256 + Integer.parseInt(fields[i]);
            }
            return "" + result;
        } else {
            long ipv4 = Long.parseLong(str);
            String result = "";
            for (int i = 0; i < N; i++) {
                result = ipv4 % 256 + "." + result;
                ipv4 /= 256;
            }
            return result.substring(0, result.length() - 1);
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String str = in.next();
            String res = convert(str);
            System.out.println(res);
        }
    }
}

34、HJ34  图片整理

Lily上课时使用字母数字图片教小朋友们学习英语单词,每次都需要把这些图片按照大小(ASCII码值从小到大)排列收好。请大家给Lily帮忙,通过代码解决。

Lily使用的图片使用字符"A"到"Z"、"a"到"z"、"0"到"9"表示。

package com.micheal;

import java.util.Scanner;

public class HJ34 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int a[] = new int[128];
            String str = in.next();
            for (int i = 0; i < str.length(); i++) {
                int k = str.charAt(i);
                a[k]++;
            }
            for (int j = 48; j < a.length; j++) {
                if (a[j] != 0)
                    for (int b = 0; b < a[j]; b++)
                        System.out.print((char) j);
            }
            System.out.println();
        }
    }
}

35、HJ35  蛇形矩阵

蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形。

例如,当输入5时,应该输出的三角形为:

1 3 6 10 15

2 5 9 14

4 8 13

7 12

11

package com.micheal;

import java.util.Scanner;

public class HJ35 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            int n = in.nextInt();
            int[][] result = new int[n][];
            int t = 1;
            for (int i = 0; i < n; i++) {
                result[i] = new int[n - i];
                for (int j = 0; j < i + 1; j++) {
                    result[i - j][j] = t;
                    t++;
                }
            }
            for (int[] a : result) {
                for (int a1 : a)
                    System.out.print(a1 + " ");
                System.out.println();
            }
        }
    }
}

36、HJ36  字符串加密

有一种技巧可以对数据进行加密,它使用一个单词作为它的密匙。下面是它的工作原理:首先,选择一个单词作为密匙,如TRAILBLAZERS。如果单词中包含有重复的字母,只保留第1个,将所得结果作为新字母表开头,并将新建立的字母表中未出现的字母按照正常字母表顺序加入新字母表。如下所示:

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

T R A I L B Z E S C D F G H J K M N O P Q U V W X Y (实际需建立小写字母的字母表,此字母表仅为方便演示)

上面其他用字母表中剩余的字母填充完整。在对信息进行加密时,信息中的每个字母被固定于顶上那行,并用下面那行的对应字母一一取代原文的字母(字母字符的大小写状态应该保留)。因此,使用这个密匙, Attack AT DAWN (黎明时攻击)就会被加密为Tpptad TP ITVH。

请实现下述接口,通过指定的密匙和明文得到密文。

数据范围:1 \le n \le 100 \1≤n≤100  ,保证输入的字符串中仅包含小写字母

package com.micheal;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Scanner;

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

            }
            System.out.println(sb.toString());
        }
    }
}

37、HJ37  统计每个月兔子的总数

有一种兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子。

例子:假设一只兔子第3个月出生,那么它第5个月开始会每个月生一只兔子。

假如兔子都不死,问第n个月的兔子总数为多少?

数据范围:输入满足 1 \le n \le 31 \1≤n≤31 

package com.micheal;

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

public class HJ37 {
    private static int[] memo;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            int month = scanner.nextInt();
            memo = new int[month + 1];
            Arrays.fill(memo, -1);
            System.out.println(dp(month));
        }

    }

    private static int dp(int n) {
        if (n <= 2) {
            return 1;
        }
        if (memo[n] != -1) {
            return memo[n];
        }
        memo[n] = dp(n - 1) + dp(n - 2);
        return memo[n];
    }
}

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

假设一个球从任意高度自由落下,每次落地后反跳回原高度的一半; 再落下, 求它在第5次落地时,共经历多少米?第5次反弹多高?

package com.micheal;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class HJ38 {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String s;
        while ((s = bf.readLine()) != null) {
            double h = Double.parseDouble(s);
            double temp = h / 2;
            for (int i = 1; i < 5; i++) {
                h += temp * 2;
                temp = temp / 2;
            }
            System.out.println(h);
            System.out.println(temp);
        }

    }
}

39、HJ39  判断两个IP是否属于同一子网

IP地址是由4个0-255之间的整数构成的,用"."符号相连。

二进制的IP地址格式有32位,例如:10000011,01101011,00000011,00011000;每八位用十进制表示就是131.107.3.24

子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。

子网掩码与IP地址结构相同,是32位二进制数,由1和0组成,且1和0分别连续,其中网络号部分全为“1”和主机号部分全为“0”。

你可以简单的认为子网掩码是一串连续的1和一串连续的0拼接而成的32位二进制数,左边部分都是1,右边部分都是0。

利用子网掩码可以判断两台主机是否中同一子网中。

若两台主机的IP地址分别与它们的子网掩码进行逻辑“与”运算(按位与/AND)后的结果相同,则说明这两台主机在同一子网中。

package com.micheal;

import java.util.Scanner;

public class HJ39 {
    public static void main(String[] args) throws Exception{
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextLine()){
            String mask = sc.nextLine();
            String ip1 = sc.nextLine();
            String ip2 = sc.nextLine();
            check( mask,  ip1,  ip2);
        }
    }
    public static void check(String mask, String ip1, String ip2){
        boolean codeMask = checkFormat(mask);
        boolean codeIp1 = checkFormatIP(ip1);
        boolean codeIp2 = checkFormatIP(ip2);
        if(!codeMask || !codeIp1 || !codeIp2){
            System.out.println(1);
            return;
        }
        long maskNum = ip2num(mask);
        long ip1Num = ip2num(ip1);
        long ip2Num = ip2num(ip2);
        if((maskNum & ip1Num) == (maskNum & ip2Num)){
            System.out.println(0);
            return;
        }
        System.out.println(2);
        return;
    }

    public static boolean checkFormat(String mask){
        String[] ss = mask.split("\\.");
        int[] m = new int[ss.length];
        for(int i = 0; i < ss.length; ++i){
            m[i] = Integer.parseInt(ss[i]);
        }
        return m[0] >= 0 && m[0] <= 255 &&
                m[1] >= 0 && m[1] <= 255 &&
                m[2] >= 0 && m[2] <= 255 &&
                m[3] >= 0 && m[3] <= 255 &&
                m[0] >= m[1] && m[1] >= m[2] && m[2] >= m[3];
    }

    public static boolean checkFormatIP(String str){
        String[] ss = str.split("\\.");
        for(String s : ss){
            int num = Integer.parseInt(s);
            if(!(num >= 0 && num <= 255)){
                return false;
            }
        }
        return true;
    }

    public static long ip2num(String str){
        String[] ss = str.split("\\.");

        long sum = 0L;
        long mul = 1L;
        for(int i = ss.length - 1; i >= 0; i--){
            long seg = Long.parseLong(ss[i]);
            sum += seg * mul;
            mul *= 256;
        }
        return sum;
    }
}

40、HJ40  统计字符

输入一行字符,分别统计出包含英文字母、空格、数字和其它字符的个数。

package com.micheal;

import java.util.Scanner;

public class HJ40 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String str = in.nextLine();
            String s1 = str.replaceAll("[A-Z]+|[a-z]+", "");
            System.out.println(str.length() - s1.length());
            String s2 = s1.replaceAll(" ", "");
            System.out.println(s1.length() - s2.length());
            String s3 = s2.replaceAll("[0-9]+", "");
            System.out.println(s2.length() - s3.length() + "\n" + s3.length());
        }
    }
}

41、HJ41  称砝码

现有n种砝码,重量互不相等,分别为 m1,m2,m3…mn ;
每种砝码对应的数量为 x1,x2,x3...xn 。现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。

注:

称重重量包括 0

package com.micheal;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;

public class HJ41 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            HashSet set = new HashSet<>();
            set.add(0);
            int n = in.nextInt();
            int[] w = new int[n];
            int[] nums = new int[n];
            for (int i = 0; i < n; i++) {
                w[i] = in.nextInt();
            }
            for (int i = 0; i < n; i++) {
                nums[i] = in.nextInt();
            }
            for (int i = 0; i < n; i++) {
                ArrayList list = new ArrayList<>(set);
                for (int j = 1; j <= nums[i]; j++) {
                    for (int k = 0; k < list.size(); k++) {
                        set.add(list.get(k) + w[i] * j);
                    }
                }
            }
            System.out.println(set.size());
        }
    }
}

42、HJ42  学英语

Jessi初学英语,为了快速读出一串数字,编写程序将数字转换成英文:

具体规则如下:
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

package com.micheal;

import java.util.ArrayList;
import java.util.Scanner;

public class HJ42 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] NUMS = {"zero", "one", "two", "three", "four", "five", "six", "seven",
                "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
                "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"};
        String[] NUMSSHI = {"zero", "ten", "twenty", "thirty", "forty", "fifty",
                "sixty", "seventy", "eighty", "ninety"};
        String[] POWER = {"", "hundred", "thousand", "million", "billion"};
        while (in.hasNext()) {
            String line = in.nextLine();
            StringBuilder sb = new StringBuilder();
            ArrayList lists = new ArrayList<>();
            if (!line.matches("\\d+")) {
                System.out.println("error");
            }
            int linenum = Integer.parseInt(line);
            int power = 1;
            while (linenum != 0) {
                if (power != 1) {
                    lists.add(POWER[power]);
                }
                int t = linenum % 1000;
                if (t % 100 <= 20) {
                    if (t % 100 != 0) {
                        lists.add(NUMS[t % 100]);
                    }
                    if (t / 100 != 0) {
                        if (t % 100 != 0) {
                            lists.add("and");
                        }
                        lists.add("hundred");
                        lists.add(NUMS[t / 100]);
                    }
                } else {
                    if (t % 10 != 0) {
                        lists.add(NUMS[t % 10]);
                    }
                    t /= 10;
                    if (t % 10 != 0) {
                        lists.add(NUMSSHI[t % 10]);
                    }
                    t /= 10;
                    if (t % 10 != 0) {
                        lists.add("and");
                        lists.add("hundred");
                        lists.add(NUMS[t % 10]);
                    }
                }
                linenum /= 1000;
                power++;
            }
            for (int i = lists.size() - 1; i >= 0; i--) {
                if (i != 0) {
                    sb.append(lists.get(i) + " ");
                } else {
                    sb.append(lists.get(i));
                }
            }
            System.out.println(sb);
        }
    }
}

43、HJ43  迷宫问题

定义一个二维数组 N*M ,如 5 × 5 数组下所示:


int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};


它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的路线。入口点为[0,0],既第一格是可以走的路。

package com.micheal;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class HJ43 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            int n = in.nextInt();
            int m = in.nextInt();
            int[][] map = new int[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    map[i][j] = in.nextInt();
                }
            }
            List path = new ArrayList<>();
            dfs(map, 0, 0, path);
            for (Pos p : path) {
                System.out.println("(" + p.x + "," + p.y + ")");
            }
        }
    }

    public static boolean dfs(int[][] map, int x, int y, List path) {
        path.add(new Pos(x, y));
        map[x][y] = 1;
        if (x == map.length - 1 && y == map[0].length - 1) {
            return true;
        }
        if (x + 1 < map.length && map[x + 1][y] == 0) {
            if (dfs(map, x + 1, y, path)) {
                return true;
            }
        }
        if (y + 1 < map[0].length && map[x][y + 1] == 0) {
            if (dfs(map, x, y + 1, path)) {
                return true;
            }
        }
        if (x - 1 > -1 && map[x - 1][y] == 0) {
            if (dfs(map, x - 1, y, path)) {
                return true;
            }
        }
        if (y - 1 > -1 && map[x][y - 1] == 0) {
            if (dfs(map, x, y - 1, path)) {
                return true;
            }
        }
        path.remove(path.size() - 1);
        map[x][y] = 0;
        return false;
    }

    public static class Pos {
        int x;
        int y;

        public Pos(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
}

44、HJ44  Sudoku

问题描述:数独(Sudoku)是一款大众喜爱的数字逻辑游戏。玩家需要根据9X9盘面上的已知数字,推算出所有剩余空格的数字,并且满足每一行、每一列、每一个3X3粗线宫内的数字均含1-9,并且不重复。

package com.micheal;

import java.util.Scanner;

public class HJ44 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int[][] board = new int[9][9];
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                board[i][j] = in.nextInt();
            }
        }
        solveSudoku(board);
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 8; j++) {
                System.out.print(board[i][j] + " ");
            }
            System.out.println(board[i][8]);
        }
    }

    public static boolean solveSudoku(int[][] board) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] != 0) {
                    continue;
                }
                for (int k = 1; k <= 9; k++) {
                    if (isValidSudoku(i, j, k, board)) {
                        board[i][j] = k;
                        if (solveSudoku(board)) {
                            return true;
                        }
                        board[i][j] = 0;
                    }
                }

                return false;
            }
        }
        return true;
    }

    public static boolean isValidSudoku(int row, int col, int val, int[][] board) {
        for (int i = 0; i < 9; i++) {
            if (board[row][i] == val) {
                return false;
            }
        }
        for (int j = 0; j < 9; j++) {
            if (board[j][col] == val) {
                return false;
            }
        }
        int startRow = (row / 3) * 3;
        int startCol = (col / 3) * 3;
        for (int i = startRow; i < startRow + 3; i++) {
            for (int j = startCol; j < startCol + 3; j++) {
                if (board[i][j] == val) {
                    return false;
                }
            }
        }
        return true;
    }
}

45、HJ45  名字的漂亮度

package com.micheal;

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

public class HJ45 {
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        while(in.hasNext()){
            int n=in.nextInt();
            for(int i=0;i=0&&s[j]>0;j--){
                    sum+=s[j]*mul;
                    mul--;
                }
                System.out.println(sum);
            }
        }
    }
}

46、HJ46  截取字符串

输入一个字符串和一个整数 k ,截取字符串的前k个字符并输出

package com.micheal;

import java.util.Scanner;

public class HJ46 {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String str = sc.next();
            int k = sc.nextInt();
            System.out.println(str.substring(0,k));
        }
    }
}

47、HJ48  从单向链表中删除指定值的节点

输入一个单向链表和一个节点的值,从单向链表中删除等于该值的节点,删除后如果链表中无节点则返回空指针。

链表的值不能重复。

构造过程,例如输入一行数据为:

6 2 1 2 3 2 5 1 4 5 7 2 2

则第一个参数6表示输入总共6个节点,第二个参数2表示头节点值为2,剩下的2个一组表示第2个节点值后面插入第1个节点值,为以下表示:

1 2 表示为

2->1

链表为2->1

3 2表示为

2->3

链表为2->3->1

5 1表示为

1->5

链表为2->3->1->5

4 5表示为

5->4

链表为2->3->1->5->4

7 2表示为

2->7

链表为2->7->3->1->5->4

最后的链表的顺序为 2 7 3 1 5 4

最后一个参数为2,表示要删掉节点为2的值

删除 结点 2

则结果为 7 3 1 5 4

package com.micheal;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class HJ48 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int total = sc.nextInt();
            int head = sc.nextInt();
            List linkedlist = new ArrayList<>();
            linkedlist.add(head);
            for (int i = 0; i < total - 1; i++) {
                int value = sc.nextInt();
                int target = sc.nextInt();
                linkedlist.add(linkedlist.indexOf(target) + 1, value);
            }
            int remove = sc.nextInt();
            linkedlist.remove(linkedlist.indexOf(remove));
            for (int i : linkedlist) {
                System.out.print(i + " ");
            }
            System.out.println();
        }
    }
}

48、HJ50  四则运算

输入一个表达式(用字符串表示),求这个表达式的值。

保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。

package com.micheal;

import java.util.Scanner;
import java.util.Stack;

public class HJ50 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        int n = s.length();
        int num1 = 0;
        int o1 = 1;
        int num2 = 1;
        int o2 = 1;
        Stack stk = new Stack<>();

        for (int i = 0; i < n; i++) {
            char c = s.charAt(i);
            if (Character.isDigit(c)) {
                int cur = 0;
                while (i < n && Character.isDigit(s.charAt(i))) {
                    cur = cur * 10 + (s.charAt(i) - '0');
                    i++;
                }
                i--;
                num2 = o2 == 1 ? num2 * cur : num2 / cur;
            } else if (c == '*' || c == '/') {
                o2 = c == '*' ? 1 : -1;
            } else if (c == '(' || c == '{' || c == '[') {
                stk.push(num1);
                stk.push(o1);
                stk.push(num2);
                stk.push(o2);

                num1 = 0;
                o1 = 1;
                num2 = 1;
                o2 = 1;
            } else if (c == '+' || c == '-') {
                if (c == '-' && (i == 0 || s.charAt(i - 1) == '(' || s.charAt(i - 1) == '[' || s.charAt(i - 1) == '{')) {
                    o1 = -1;
                    continue;
                }
                num1 = num1 + o1 * num2;
                o1 = (c == '+' ? 1 : -1);
                num2 = 1;
                o2 = 1;
            } else {
                int cur = num1 + o1 * num2;
                o2 = stk.pop();
                num2 = stk.pop();
                o1 = stk.pop();
                num1 = stk.pop();

                num2 = o2 == 1 ? num2 * cur : num2 / cur;
            }
        }
        System.out.println(num1 + o1 * num2);
    }
}

49、HJ51  输出单向链表中倒数第k个结点

输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第1个结点为链表的尾指针。

链表结点定义如下:

struct ListNode
{
    int m_nKey;
    ListNode* m_pNext;
};

正常返回倒数第k个结点指针,异常返回空指针.

要求:

(1)正序构建链表;

(2)构建后要忘记链表长度。

package com.micheal;

import java.util.Scanner;

public class HJ51 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        while (scan.hasNext()) {
            int num = scan.nextInt();
            ListNode header = new ListNode();
            for (int i = 0; i < num; i++) {
                int value = scan.nextInt();
                ListNode node = new ListNode(value, header.next);
                header.next = node;
            }
            int target = scan.nextInt();
            for (int i = 0; i < target; i++) {
                header = header.next;
            }
            System.out.println(header.value);
        }

    }
}

class ListNode {
    int value;
    ListNode next;

    public ListNode() {

    }

    public ListNode(int value, ListNode next) {
        this.value = value;
        this.next = next;
    }
}

50、HJ52  计算字符串的编辑距离

Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。编辑距离的算法是首先由俄国科学家 Levenshtein 提出的,故又叫 Levenshtein Distance 。

例如:

字符串A: abcdefg

字符串B: abcdef

通过增加或是删掉字符 ”g” 的方式达到目的。这两种方案都需要一次操作。把这个操作所需要的次数定义为两个字符串的距离。

要求:

给定任意两个字符串,写出一个算法计算它们的编辑距离。

package com.micheal;

import java.util.Scanner;

public class HJ52 {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String a = sc.nextLine();
            String b = sc.nextLine();
            int[][] dp = new int[a.length()+1][b.length()+1];  
            for(int i=1; i<=a.length(); i++){  
                dp[i][0] = i;
            }
            for(int i=1; i<=b.length(); i++){  
                dp[0][i] = i;
            }
            for(int i=1; i<=a.length(); i++){
                for(int j=1; j<=b.length(); j++){
                    if(a.charAt(i-1)==b.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-1]+1, dp[i][j-1]+1));  
                    }
                }
            }
            System.out.println(dp[a.length()][b.length()]);
        }
    }
}

51、HJ53  杨辉三角的变形

华为机试算法整理_第1张图片

以上三角形的数阵,第一行只有一个数1,以下每行的每个数,是恰好是它上面的数、左上角数和右上角的数,3个数之和(如果不存在某个数,认为该数就是0)。

求第n行第一个偶数出现的位置。如果没有偶数,则输出-1。例如输入3,则输出2,输入4则输出3,输入2则输出-1。

package com.micheal;

import java.util.Scanner;

public class HJ53 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int num = sc.nextInt();
            if (num == 1 || num == 2) {
                System.out.println(-1);
            } else {
                if (num % 2 == 1) {
                    System.out.println(2);
                } else if (num % 4 == 2) {
                    System.out.println(4);
                } else {
                    System.out.println(3);
                }
            }
        }
    }
}

 52、HJ54  表达式求值

给定一个字符串描述的算术表达式,计算出结果值。

输入字符串长度不超过 100 ,合法的字符包括 ”+, -, *, /, (, )” , ”0-9” 。

package com.micheal;

import java.util.Scanner;
import java.util.Stack;

public class HJ54 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        s = s.replace("{", "(");
        s = s.replace("[", "(");
        s = s.replace("}", ")");
        s = s.replace("]", ")");
        System.out.println(slove(s));
    }

    public static int slove(String s) {
        Stack stack = new Stack<>();
        int n = s.length();
        char[] chs = s.toCharArray();
        int index = 0;
        char sign = '+';
        int number = 0;
        for (int i = 0; i < n; i++) {
            char ch = chs[i];
            if (ch == ' ') continue;
            if (Character.isDigit(ch)) {
                number = number * 10 + ch - '0';
            }
            if (ch == '(') {
                int j = i + 1;
                int count = 1;
                while (count > 0) {
                    if (chs[j] == ')') count--;
                    if (chs[j] == '(') count++;
                    j++;
                }
                number = slove(s.substring(i + 1, j - 1));
                i = j - 1;
            }
            if (!Character.isDigit(ch) || i == n - 1) {
                if (sign == '+') {
                    stack.push(number);
                } else if (sign == '-') {
                    stack.push(-1 * number);
                } else if (sign == '*') {
                    stack.push(stack.pop() * number);
                } else if (sign == '/') {
                    stack.push(stack.pop() / number);
                }
                sign = ch;
                number = 0;
            }
        }
        int ans = 0;
        while (!stack.isEmpty()) {
            ans += stack.pop();
        }
        return ans;
    }
}

53、HJ55  挑7

输出 1到n之间 的与 7 有关数字的个数。

一个数与7有关是指这个数是 7 的倍数,或者是包含 7 的数字(如 17 ,27 ,37 ... 70 ,71 ,72 ,73...)

package com.micheal;

import java.util.Scanner;

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

54、HJ56  完全数计算

完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。

它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。

例如:28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。

输入n,请输出n以内(含n)完全数的个数。

package com.micheal;

import java.util.Scanner;

public class HJ56 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            int n = in.nextInt();
            if (n < 6) {
                System.out.println(0);
                continue;
            }
            int count = 0;
            for (int t = 6; t <= n; t++) {
                int sum = 0;
                for (int i = 1; i <= t / 2; i++) {
                    if (t % i == 0)
                        sum += i;
                }
                if (sum == t)
                    count++;
            }
            System.out.println(count);
        }
    }
}

55、HJ57  高精度整数加法

输入两个用字符串 str 表示的整数,求它们所表示的数之和。

package com.micheal;

import java.math.BigInteger;
import java.util.Scanner;

public class HJ57 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        while (scan.hasNext()) {
            String s1 = scan.next();
            String s2 = scan.next(); //输入两个数
            BigInteger a = new BigInteger(s1); //将字符串转成大整数
            BigInteger b = new BigInteger(s2);
            System.out.println(a.add(b)); //大整数相加
        }
    }
}

56、HJ58  输入n个整数,输出其中最小的k个

输入n个整数,找出其中最小的k个整数并按升序输出

package com.micheal;

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

public class HJ58 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            int k = sc.nextInt();
            int[] arr = new int[n];
            for (int i = 0; i < n; i++) {
                arr[i] = sc.nextInt();
            }
            Arrays.sort(arr);
            for (int i = 0; i < k; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
    }
}

57、HJ59  找出字符串中第一个只出现一次的字符

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

package com.micheal;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;

public class HJ59 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String str = sc.next();
            Map map = new LinkedHashMap<>();
            for (int i = 0; i < str.length(); i++) {
                if (map.containsKey(str.charAt(i))) {
                    map.put(str.charAt(i), map.get(str.charAt(i)) + 1);
                } else {
                    map.put(str.charAt(i), 1);
                }
            }
            char ch = 0;
            for (Map.Entry entry : map.entrySet()) {
                if (entry.getValue() == 1) {
                    ch = entry.getKey();
                    break;
                }
            }
            if (ch == 0) {
                System.out.println(-1);
            } else {
                System.out.println(ch);
            }
        }
    }
}

58、HJ60  查找组成一个偶数最接近的两个素数

package com.micheal;

import java.util.Scanner;

public class HJ60 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            int num = scanner.nextInt();
            solution(num);
        }
    }

    private static void solution(int num) {
        //如num=10, 遍历:5,6,7,8
        // 从最接近的两个中位数开始处理判断
        for (int i = num / 2; i < num - 1; i++) {
            if (isPrime(i) && isPrime(num - i)) {
                System.out.println((num - i) + "\n" + i);
                return;
            }
        }
    }

    // 判断是否素数
    private static boolean isPrime(int num) {
        for (int i = 2; i <= Math.sqrt(num); i++) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }
}

59、HJ61  放苹果

把m个同样的苹果放在n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?

注意:如果有7个苹果和3个盘子,(5,1,1)和(1,5,1)被视为是同一种分法。

package com.micheal;

import java.util.Scanner;

public class HJ61 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextInt()) {
            System.out.println(count(sc.nextInt(), sc.nextInt()));
        }
        sc.close();
    }

    public static int count(int m, int n) {
        if (m < 0 || n <= 0)
            return 0;
        if (m == 1 || n == 1 || m == 0)
            return 1;
        return count(m, n - 1) + count(m - n, n);
    }
}

60、HJ62 查找输入整数二进制中1的个数

输入一个正整数,计算它在二进制下的1的个数。

注意多组输入输出!!!!!!

package com.micheal;

import java.util.Scanner;

public class HJ62 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            int a = in.nextInt();
            String b=Integer.toBinaryString(a);
            String c=b.replaceAll("1","");
            System.out.println(b.length()-c.length());
        }
    }
}

61、HJ63  DNA序列

一个 DNA 序列由 A/C/G/T 四个字母的排列组合组成。 G 和 C 的比例(定义为 GC-Ratio )是序列中 G 和 C 两个字母的总的出现次数除以总的字母数目(也就是序列长度)。在基因工程中,这个比例非常重要。因为高的 GC-Ratio 可能是基因的起始点。

给定一个很长的 DNA 序列,以及限定的子串长度 N ,请帮助研究人员在给出的 DNA 序列中从左往右找出 GC-Ratio 最高且长度为 N 的第一个子串。

DNA序列为 ACGT 的子串有: ACG , CG , CGT 等等,但是没有 AGT , CT 等等

package com.micheal;

import java.util.Scanner;

public class HJ63 {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        while (scan.hasNext()) {
            String data = scan.nextLine();
            int len = Integer.parseInt(scan.nextLine());
            double max = 0.0;
            String result = "";
            for (int i = 0; i < data.length() - len + 1; i++) {
                String str = data.substring(i, len + i);
                String str2 = str.replaceAll("[^CG]", "");
                double x = str2.length() * 1.0 / str.length();
                if (x > max) {
                    result = str;
                    max = x;
                    if (x == 1.0) {
                        break;
                    }
                }
            }
            System.out.println(result);
        }
    }
}

62、HJ64  MP3光标位置

MP3 Player因为屏幕较小,显示歌曲列表的时候每屏只能显示几首歌曲,用户要通过上下键才能浏览所有的歌曲。为了简化处理,假设每屏只能显示4首歌曲,光标初始的位置为第1首歌。

package com.micheal;

import java.util.Scanner;

public class HJ64 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            String cmd = sc.next();
            parseCmd(cmd, n);
        }
    }

    public static void parseCmd(String commands, int n) {
        int start = 1;
        int end = Math.min(n, 4);
        int index = 1;
        for (int i = 0; i < commands.length(); i++) {
            if (commands.charAt(i) == 'U') {
                index = (index - 1 - 1 + n) % n + 1;
            } else if (commands.charAt(i) == 'D') {
                index = index % n + 1;
            }
            if (index < start) {
                start = index;
                end = start + 3;
            } else if (index > end) {
                end = index;
                start = end - 3;
            }
        }
        for (int i = start; i <= end; i++) {
            System.out.print(i + " ");
        }
        System.out.println();
        System.out.println(index);
    }
}

63、HJ65  查找两个字符串a,b中的最长公共子串

查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。

注:子串的定义:将一个字符串删去前缀和后缀(也可以不删)形成的字符串。请和“子序列”的概念分开!

package com.micheal;

import java.util.Scanner;

public class HJ65 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String s1 = sc.nextLine();
            String s2 = sc.nextLine();
            longString(s1, s2);
        }
    }

    public static void longString(String s1, String s2) {
        String shortStr = s1.length() < s2.length() ? s1 : s2;
        String longStr = s1.length() > s2.length() ? s1 : s2;
        int shortLen = shortStr.length();
        int maxLen = 0, start = 0;
        for (int i = 0; i < shortLen; i++) {
            if (shortLen - i + 1 <= maxLen) {
                break;
            }
            for (int j = i, k = shortLen; k > j; k--) {
                String subStr = shortStr.substring(i, k);
                if (longStr.contains(subStr) && maxLen < subStr.length()) {
                    maxLen = subStr.length();
                    start = j;
                    break;
                }
            }
        }
        System.out.println(shortStr.substring(start, start + maxLen));
    }
}

64、HJ66  配置文件恢复

有6条配置命令,它们执行的结果分别是:

命   令 执   行
reset reset what
reset board board fault
board add where to add
board delete no board at all
reboot backplane impossible
backplane abort install first
he he unknown command

注意:he he不是命令。

为了简化输入,方便用户,以“最短唯一匹配原则”匹配(注:需从首字母开始进行匹配):

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”

注意:有多组输入。

package com.micheal;

import java.util.Scanner;
import java.util.regex.Pattern;

public class HJ66 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String[] commands = {"reset", "reset board", "board add", "board delete",
                "reboot backplane", "backplane abort"};
        String[] responses = {"reset what", "board fault", "where to add",
                "no board at all", "impossible", "install first", "unknown command"};
        while (in.hasNextLine()) {
            String input = in.nextLine();
            if (input.isEmpty()) {//阻止最后一行的空行输出unknown command
                continue;
            }
            int match_num = 0;//记录有多少match的指令
            int index = 6;//记录最后一个match的指令的下表
            for (int i = 0; i < commands.length; i++) {
                if (match(input, commands[i])) {
                    match_num++;
                    index = i;
                }
            }
            if (match_num != 1) {
                index = 6;
            }
            System.out.println(responses[index]);

        }
    }

    // 正则表达式匹配
    public static boolean match(String input, String command) {
        if (input.isEmpty()) {//空白输入不应该有符合的结果
            return false;
        }
        String[] inputs = input.split(" ");
        String[] commands = command.split(" ");
        if (inputs.length == 1 && commands.length == 1) {
            String pattern = input + ".*";
            return Pattern.matches(pattern, command);
        } else if (inputs.length == 2 && commands.length == 2) {
            String pattern_1 = inputs[0] + ".*";
            String pattern_2 = inputs[1] + ".*";
            return Pattern.matches(pattern_1, commands[0]) && Pattern.matches(pattern_2, commands[1]);
        }
        return false;
    }
}

65、HJ67  24点游戏算法

给出4个1-10的数字,通过加减乘除运算,得到数字为24就算胜利,除法指实数除法运算,运算符仅允许出现在两个数字之间,本题对数字选取顺序无要求,但每个数字仅允许使用一次,且需考虑括号运算

此题允许数字重复,如3 3 4 4为合法输入,此输入一共有两个3,但是每个数字只允许使用一次,则运算过程中两个3都被选取并进行对应的计算操作。

package com.micheal;

import java.util.Scanner;

public class HJ67 {
    static int[] nums = new int[4];
    static boolean[] visit = new boolean[4];
    static int flag = 0;

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String[] a = in.nextLine().split(" ");
            for (int i = 0; i < 4; i++)
                nums[i] = Integer.parseInt(a[i]);
            dfs(0, 0);
            System.out.println(flag == 1);
        }

    }

    static boolean dfs(int u, float tmp) {
        if (tmp == 24 && u == 4) {
            flag = 1;
            return true;
        }
        for (int i = 0; i < 4; i++) {
            if (visit[i] == false) {
                visit[i] = true;
                if (dfs(u + 1, tmp + nums[i]) ||
                        dfs(u + 1, tmp - nums[i]) ||
                        dfs(u + 1, tmp * nums[i]) ||
                        dfs(u + 1, tmp / nums[i])) {
                    return true;
                }
                visit[i] = false;
            }
        }
        return false;
    }
}

66、HJ68  成绩排序

给定一些同学的信息(名字,成绩)序列,请你将他们的信息按照成绩从高到低或从低到高的排列,相同成绩

都按先录入排列在前的规则处理。

例示:
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代表从低到高

package com.micheal;

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

public class HJ68 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        HashMap map = new HashMap<>();
        while (sc.hasNextLine()) {
            int n = Integer.parseInt(sc.nextLine());
            int flag = Integer.parseInt(sc.nextLine());
            int[][] score = new int[n][2];
            for (int i = 0; i < n; i++) {
                String[] nameAndScore = sc.nextLine().split(" ");
                score[i][0] = i;
                score[i][1] = Integer.parseInt(nameAndScore[1]);
                map.put(i, nameAndScore[0]);
            }
            Arrays.sort(score, (o1, o2) -> {
                if (flag == 0) {
                    return o2[1] - o1[1];
                } else {
                    return o1[1] - o2[1];
                }
            });
            for (int i = 0; i < n; i++) {
                System.out.println(map.get(score[i][0]) + " " + score[i][1]);
            }
        }
    }
}

67、HJ69  矩阵乘法

如果A是个x行y列的矩阵,B是个y行z列的矩阵,把A和B相乘,其结果将是另一个x行z列的矩阵C。这个矩阵的每个元素是由下面的公式决定的

矩阵的大小不超过100*100

输入描述:

第一行包含一个正整数x,代表第一个矩阵的行数
第二行包含一个正整数y,代表第一个矩阵的列数和第二个矩阵的行数
第三行包含一个正整数z,代表第二个矩阵的列数
之后x行,每行y个整数,代表第一个矩阵的值
之后y行,每行z个整数,代表第二个矩阵的值

package com.micheal;

import java.util.Scanner;

public class HJ69 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextInt()) {
            int x = sc.nextInt();
            int y = sc.nextInt();
            int z = sc.nextInt();
            int[][] a = new int[x][y];
            for (int i = 0; i < x; i++) {
                for (int j = 0; j < y; j++) {
                    a[i][j] = sc.nextInt();
                }
            }
            int[][] b = new int[y][z];
            for (int i = 0; i < y; i++) {
                for (int j = 0; j < z; j++) {
                    b[i][j] = sc.nextInt();
                }
            }
            int[][] c = new int[x][z];
            for (int i = 0; i < x; i++) {
                for (int j = 0; j < z; j++) {
                    for (int k = 0; k < y; k++) {
                        c[i][j] += a[i][k] * b[k][j];
                    }
                }
            }
            for (int i = 0; i < x; i++) {
                for (int j = 0; j < z; j++) {
                    System.out.print(c[i][j]);
                    if (j != z - 1) {
                        System.out.print(" ");
                    }
                }
                System.out.println("");
            }
        }
    }
}

68、HJ70  矩阵乘法计算量估算 

矩阵乘法的运算量与矩阵乘法的顺序强相关。
例如:

A是一个50×10的矩阵,B是10×20的矩阵,C是20×5的矩阵

计算A*B*C有两种顺序:((AB)C)或者(A(BC)),前者需要计算15000次乘法,后者只需要3500次。

编写程序计算不同的计算顺序需要进行的乘法次数。

package com.micheal;

import java.util.Scanner;
import java.util.Stack;

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

69、HJ71  字符串通配符 

问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。
要求:
实现如下2个通配符:
*:匹配0个或以上的字符(注:能被*和?匹配的字符仅由英文字母和数字0到9组成,下同)
?:匹配1个字符

注意:匹配时不区分大小写。

package com.micheal;

import java.util.Scanner;

public class HJ71 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String s1 = in.nextLine();
            String s2 = in.nextLine();
            System.out.println(helper(s1, s2, 0, 0));
        }
    }

    private static boolean helper(String s1, String s2, int p1, int p2) {
        if (p1 == s1.length() && p2 == s2.length()) {
            return true;
        } else if (p1 == s1.length() || p2 == s2.length()) {
            return false;
        }
        if (s1.charAt(p1) == '*') {
            return helper(s1, s2, p1, p2 + 1) || helper(s1, s2, p1 + 1, p2 + 1);
        } else if (s1.charAt(p1) == '?' || s1.charAt(p1) == s2.charAt(p2)) {
            return helper(s1, s2, p1 + 1, p2 + 1);
        } else {
            return false;
        }
    }
}

70、HJ72  百钱买百鸡问题

公元五世纪,我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?

现要求你打印出所有花一百元买一百只鸡的方式。

package com.micheal;

import java.util.Scanner;

public class HJ72 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()){
            int n = in.nextInt();
            for (int x = 0; x <= 14; x++) {
                if ((100 - 7* x) % 4 == 0){
                    int y = (100-7*x) / 4;
                    int z = 100 - x - y;
                    System.out.println(x + " " + y + " " + z);
                }
            }
        }
    }
}

71、HJ73  计算日期到天数转换

根据输入的日期,计算是这一年的第几天。

保证年份为4位数且日期合法。

进阶:时间复杂度:O(n)\O(n) ,空间复杂度:O(1)\O(1) 

package com.micheal;

import java.util.Calendar;
import java.util.Scanner;

public class HJ73 {
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        int y=in.nextInt();
        int m=in.nextInt();
        int d=in.nextInt();
        Calendar c1=Calendar.getInstance();//实例化
        c1.set(y, m-1, d);//注意月份从0开始
        System.out.println(c1.get(Calendar.DAY_OF_YEAR));
    }
}

72、HJ74  参数解析 

在命令行输入如下命令:

xcopy /s c:\\ d:\\e,

各个参数如下:

参数1:命令字xcopy

参数2:字符串/s

参数3:字符串c:\\

参数4: 字符串d:\\e

请编写一个参数解析程序,实现将命令行各个参数解析出来。

解析规则:

1.参数分隔符为空格
2.对于用""包含起来的参数,如果中间有空格,不能解析为多个参数。比如在命令行输入xcopy /s "C:\\program files" "d:\"时,参数仍然是4个,第3个参数应该是字符串C:\\program files,而不是C:\\program,注意输出参数时,需要将""去掉,引号不存在嵌套情况。
3.参数不定长

4.输入由用例保证,不会出现不符合要求的输入

package com.micheal;

import java.util.ArrayList;
import java.util.Scanner;

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

73、HJ75  公共子串计算

给定两个只包含小写字母的字符串,计算两个字符串的最大公共子串的长度。

注:子串的定义指一个字符串删掉其部分前缀和后缀(也可以不删)后形成的字符串。

package com.micheal;

import java.util.Scanner;

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

74、HJ76 

验证尼科彻斯定理,即:任何一个整数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个连续奇数之和的形式输出。

package com.micheal;

import java.util.Scanner;

public class HJ76 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            int n = in.nextInt();
            long sum = (long)Math.pow(n,3);
            int a1 = (int)sum/n - (n - 1);
            StringBuilder sb = new StringBuilder(Integer.toString(a1));
            for(int i = 1; i < n; i++){
                a1 = a1 + 2;
                sb.append("+");
                sb.append(a1);
            }
            System.out.println(sb);
        }
    }
}

75、HJ77  火车进站

给定一个正整数N代表火车数量,0

要求输出所有火车出站的方案,以字典序排序输出。

package com.micheal;

import java.util.*;

public class HJ77 {
    static Deque stack;
    static int[] nums, outNums;
    static int n;
    static List res;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        nums = new int[n];
        for (int i=0; i();
        res = new ArrayList<>();
        dfs(0, 0);
        Collections.sort(res);
        for (String str:res) System.out.println(str);
    }

    public static void dfs(int i, int cnt) {
        Deque tmp = new LinkedList<>();
        stack.push(nums[i]);
        if (i==n-1) {
            while (stack.size() > 0) {
                tmp.push(stack.peek());
                outNums[cnt++] = stack.pop();
            }
            while (tmp.size() > 1) stack.push(tmp.pop());
            StringBuilder sb = new StringBuilder();
            for (int outNum:outNums) sb.append(outNum).append(" ");
            res.add(sb.toString());
        }
        else {
            int size = stack.size();
            dfs(i+1, cnt);
            for (int j=0; j 1) stack.push(tmp.pop());
        }
    }
}

76、HJ80  整型数组合并

题目标题:

将两个整型数组按照升序合并,并且过滤掉重复数组元素。

输出时相邻两数之间没有空格。

package com.micheal;

import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

public class HJ80 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            Set set = new TreeSet<>();
            int size1 = sc.nextInt();
            for (int i = 0; i < size1; i++) {
                set.add(sc.nextLong());
            }
            int size2 = sc.nextInt();
            for (int i = 0; i < size2; i++) {
                set.add(sc.nextLong());
            }
            for (long n : set) {
                System.out.print(n);
            }
            System.out.println();
        }

    }
}

77、HJ81  字符串字符匹配

判断短字符串S中的所有字符是否在长字符串T中全部出现。

请注意本题有多组样例输入。

package com.micheal;

import java.util.Scanner;

public class HJ81 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String a = sc.nextLine();
            String b = sc.nextLine();
            String[] array = a.split("");
            int count = 0;
            for (int i = 0; i < array.length; i++) {
                if (b.contains(array[i])) {
                    count++;
                }
            }
            if (count == array.length) {
                System.out.println(true);
            } else {
                System.out.println(false);
            }
        }

    }
}

78、HJ82  将真分数分解为埃及分数

分子为1的分数称为埃及分数。现输入一个真分数(分子比分母小的分数,叫做真分数),请将该分数分解为埃及分数。如:8/11 = 1/2+1/5+1/55+1/110。

package com.micheal;

import java.util.Scanner;

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

79、HJ83  二维数组操作

有一个m*n\m∗n 大小的数据表,你会依次进行以下5种操作:

1.输入m\m 和n\n ,初始化m*n\m∗n 大小的表格。

2.输入x_1x1​、y_1y1​、x_2x2​、y_2y2​,交换坐标在(x_1,y_1)(x1​,y1​)和(x_2,y_2)(x2​,y2​)的两个数。

3.输入x\x ,在第x\x 行上方添加一行。

4.输入y\y ,在第y\y 列左边添加一列。

5.输入x\x 、y\y ,查找坐标为(x,y)\(x,y) 的单元格的值。

请编写程序,判断对表格的各种操作是否合法。

详细要求:

1.数据表的最大规格为9行*9列,对表格进行操作时遇到超出规格应该返回错误。

2.对于插入操作,如果插入后行数或列数超过9了则应返回错误。如果插入成功了则将数据表恢复至初始化的m*n\m∗n 大小,多出的数据则应舍弃。

3.所有输入坐标操作,对m*n\m∗n 大小的表格,行号坐标只允许0~m-1,列号坐标只允许0~n-1。超出范围应该返回错误。

本题含有多组样例输入!行列从0开始标号

package com.micheal;

import java.util.Scanner;

public class HJ83 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int r, c, r1, c1, r2, c2, ri, ci, rt, ct;
        while (sc.hasNext()) {
            r = sc.nextInt();
            c = sc.nextInt();
            r1 = sc.nextInt();
            c1 = sc.nextInt();
            r2 = sc.nextInt();
            c2 = sc.nextInt();
            ri = sc.nextInt();
            ci = sc.nextInt();
            rt = sc.nextInt();
            ct = sc.nextInt();
            if (r <= 9 && c <= 9) {
                System.out.println(0);
            } else {
                System.out.println(-1);
            }
            if ((r1 < r && r2 < r) && (c1 < c && c2 < c)) {
                System.out.println(0);
            } else {
                System.out.println(-1);
            }
            if (ri < r && r < 9) {
                System.out.println(0);
            } else {
                System.out.println(-1);
            }
            if (ci < c && c < 9) {
                System.out.println(0);
            } else {
                System.out.println(-1);
            }
            if (rt < r && ct < c) {
                System.out.println(0);
            } else {
                System.out.println(-1);
            }
        }
        sc.close();
    }
}

80、HJ84  统计大写字母个数

找出给定字符串中大写字符(即'A'-'Z')的个数。

数据范围:字符串长度:1\le |s|\le 250\1≤∣s∣≤250 

字符串中可能包含空格或其他字符

进阶:时间复杂度:O(n)\O(n) ,空间复杂度:O(n)\O(n) 

package com.micheal;

import java.util.Scanner;

public class HJ84 {
    public static void main(String args[]) {
        Scanner input = new Scanner(System.in);
        while (input.hasNext()) {
            String s = input.nextLine();
            System.out.println(count(s));
        }
    }

    public static int count(String s) {
        int count = 0;
        char[] cs = s.toCharArray();
        for (char c : cs) {
            if (c >= 'A' && c <= 'Z') {
                count++;
            }
        }
        return count;
    }
}

81、HJ85  最长回文子串

给定一个仅包含小写字母的字符串,求它的最长回文子串的长度。

所谓回文串,指左右对称的字符串。

所谓子串,指一个字符串删掉其部分前缀和后缀(也可以不删)的字符串

数据范围:字符串长度1\le s\le 350\1≤s≤350 

进阶:时间复杂度:O(n)\O(n) ,空间复杂度:O(n)\O(n) 

package com.micheal;

import java.util.Scanner;

public class HJ85 {
    public static void main(String args[]) {
        Scanner input = new Scanner(System.in);
        String s = input.nextLine();
        int max = 0;
        for (int i = 0; i < s.length(); i++) {
            for (int j = s.length(); j > i; j--) {
                String toBeJuged = s.substring(i, j);
                if (isPalindromeString(toBeJuged)) {
                    max = Math.max(max, j - i);
                }
            }
        }
        System.out.print(max);
    }

    static boolean isPalindromeString(String s) {
        return s.equals(new StringBuilder(s).reverse().toString());
    }
}

82、HJ86  求最大连续bit数 

求一个int类型数字对应的二进制数字中1的最大连续数,例如3的二进制为00000011,最大连续2个1

package com.micheal;

import java.util.Scanner;

public class HJ86 {
    public static void main(String args[]) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextInt()) {
            int num = scanner.nextInt();
            String binaryStr = Integer.toBinaryString(num);
            String[] strArray = binaryStr.split("0");
            int result = 0;
            for (int i = 0; i < strArray.length; i++) {
                if (strArray[i].length() > result) {
                    result = strArray[i].length();
                }
            }
            System.out.println(result);
        }
    }
}

83、HJ87  密码强度等级

密码按如下规则进行计分,并根据不同的得分为密码进行安全等级划分。
一、密码长度:
5 分: 小于等于4 个字符
10 分: 5 到7 字符
25 分: 大于等于8 个字符
二、字母:
0 分: 没有字母
10 分: 密码里的字母全都是小(大)写字母
20 分: 密码里的字母符合”大小写混合“
三、数字:
0 分: 没有数字
10 分: 1 个数字
20 分: 大于1 个数字
四、符号:
0 分: 没有符号
10 分: 1 个符号
25 分: 大于1 个符号
五、奖励(只能选符合最多的那一种奖励):
2 分: 字母和数字
3 分: 字母、数字和符号

5 分: 大小写字母、数字和符号

最后的评分标准:
>= 90: 非常安全
>= 80: 安全(Secure)
>= 70: 非常强
>= 60: 强(Strong)
>= 50: 一般(Average)
>= 25: 弱(Weak)
>= 0:  非常弱(Very_Weak)
对应输出为:
VERY_SECURE
SECURE
VERY_STRONG
STRONG
AVERAGE
WEAK
VERY_WEAK
请根据输入的密码字符串,进行安全评定。

package com.micheal;

import java.util.Scanner;

public class HJ87 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            char[] ch = in.nextLine().toCharArray();
            int score = 0;
            int len = ch.length;
            if (len <= 4) score += 5;
            else if (len > 4 && len < 8) score += 10;
            else score += 25;
            int upCount = 0;
            int lowCount = 0;
            int numCount = 0;
            int sigCount = 0;
            for (int i = 0; i < len; i++) {
                if (Character.isUpperCase(ch[i])) ++upCount;
                else if (Character.isLowerCase(ch[i])) ++lowCount;
                else if (Character.isDigit(ch[i])) ++numCount;
                else ++sigCount;
            }
            if ((upCount > 0 && lowCount == 0) || (upCount == 0 && lowCount > 0)) score += 10;
            else if (upCount > 0 && lowCount > 0) score += 20;
            else score += 0;
            if (numCount == 1) score += 10;
            else if (numCount > 1) score += 20;
            else score += 0;
            if (sigCount == 1) score += 10;
            else if (sigCount > 1) score += 25;
            else score += 0;
            if (numCount > 0 && upCount > 0 && lowCount > 0 && sigCount > 0) score += 5;
            else if (numCount > 0 && sigCount > 0 && (upCount > 0 || lowCount > 0)) score += 3;
            else if (numCount > 0 && (upCount > 0 || lowCount > 0)) score += 2;
            if (score >= 90) System.out.println("VERY_SECURE");
            else if (score >= 80) System.out.println("SECURE");
            else if (score >= 70) System.out.println("VERY_STRONG");
            else if (score >= 60) System.out.println("STRONG");
            else if (score >= 50) System.out.println("AVERAGE");
            else if (score >= 25) System.out.println("WEAK");
            else System.out.println("VERY_WEAK");
        }
    }
}

84、HJ88  扑克牌大小

扑克牌游戏大家应该都比较熟悉了,一副牌由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)输入的两手牌不会出现相等的情况。

package com.micheal;

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

public class HJ88 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String s = in.nextLine();
            String[] arr = s.split("-");
            System.out.println(helper(arr[0], arr[1]));
        }
    }

    private static String helper(String s1, String s2) {
        HashMap map = new HashMap() {
            {
                put("A", 14);
                put("2", 15);
                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("joker", 16);
                put("JOKER", 17);
            }
        };
        if (s1.equals("joker JOKER") || s1.equals("JOKER joker")) {
            return s1;
        } else if (s2.equals("joker JOKER") || s2.equals("JOKER joker")) {
            return s2;
        }
        String[] arr1 = s1.split(" ");
        int n1 = map.get(arr1[0]);
        String[] arr2 = s2.split(" ");
        int n2 = map.get(arr2[0]);
        if (isBoom(s2) && isBoom(s1)) {
            return n1 > n2 ? s1 : s2;
        } else if (isBoom(s2)) {
            return s2;
        } else if (isBoom(s1)) {
            return s1;
        } else if (arr1.length == arr2.length) {
            return n1 > n2 ? s1 : s2;
        } else {
            return "ERROR";
        }
    }

    private static boolean isBoom(String s1) {
        String[] temp = s1.split(" ");
        if (temp.length != 4) return false;
        String cur = temp[0];
        for (int i = 1; i < 4; i++) {
            if (!cur.equals(temp[i])) return false;
        }
        return true;
    }
}

85、HJ89  24点运算

计算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

数据范围:一行由4张牌组成的字符串

package com.micheal;

import java.util.LinkedList;
import java.util.Scanner;

public class HJ89 {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        LinkedList list1 = new LinkedList<>();
        LinkedList list = new LinkedList<>();
        LinkedList list2 = new LinkedList<>();
        list2.add("0");
        list2.add("A");
        for (int i = 2; i <= 10; i++){
            list2.add(Integer.toString(i));
        }
        list2.add("J");
        list2.add("Q");
        list2.add("K");
        while (sc.hasNext()){
            list1.add(sc.next());
        }
        int flag = 0;
        for (int i = 0; i < 4 ; i++){
            String cur = list1.get(i);
            if (cur.equals("JOKER") || cur.equals("joker")){
                System.out.println("ERROR");
                flag = -1;
                break;
            }else if (cur.equals("A")){
                list.add(1);
            }else if (cur.equals("K")){
                list.add(13);
            }else if (cur.equals("Q")){
                list.add(12);
            }else if (cur.equals("J")){
                list.add(11);
            }else{
                list.add(Integer.valueOf(cur));
            }
        }
        if (flag == 0){
            for (int i = 0; i < 4; i++){
                for (int j = 0; j < 4; j++){
                    if (j == i) continue;
                    if(flag == 1) break;
                    for (int k = 0; k < 4; k++){
                        if (k == i || k == j) continue;
                        if(flag == 1) break;
                        for (int p = 0; p < 4; p++){
                            if (p == i || p == j || p == k) continue;
                            if(flag == 1) break;
                            String out = helper(list.get(i), list.get(j), list.get(k),list.get(p));
                            if (!out.equals("NONE")){
                                String res = "";
                                res += list2.get(list.get(i));
                                res += out.substring(0,1);
                                res += list2.get(list.get(j));
                                res += out.substring(1,2);
                                res += list2.get(list.get(k));
                                res += out.substring(2,3);
                                res += list2.get(list.get(p));
                                System.out.println(res);
                                flag = 1;
                            }
                        }
                    }
                }
            }
            if (flag == 0) System.out.println("NONE");
        }
    }
    static public String helper(int a, int b){
        if (a * b == 24) return "*";
        else if (a + b == 24) return "+";
        else if (b != 0 && a % b == 0 && a / b == 24) return "/";
        else if (a - b == 24) return "-";
        else return "NONE";
    }
    static public String helper(int a, int b, int c){
        if (!helper(a * b, c).equals("NONE")) return "*" + helper(a * b, c);
        else if (!helper(a + b, c).equals("NONE")) return "+" + helper(a + b, c);
        else if (!helper(a - b, c).equals("NONE")) return "-" + helper(a - b, c);
        else if (b != 0 && a % b == 0 && !helper(a / b, c).equals("NONE")) return "/" + helper(a * b, c);
        else return "NONE";
    }
    static public String helper(int a, int b, int c, int d){
        if (!helper(a * b, c, d).equals("NONE")) return "*" + helper(a * b, c, d);
        else if (!helper(a + b, c, d).equals("NONE")) return "+" + helper(a + b, c, d);
        else if (!helper(a - b, c, d).equals("NONE")) return "-" + helper(a - b, c, d);
        else if (b != 0 && a % b == 0 && !helper(a / b, c, d).equals("NONE")) return "/" + helper(a * b, c, d);
        else return "NONE";
    }
}

86、HJ90  合法IP

PV4地址可以用一个32位无符号整数来表示,一般用点分方式来显示,点将IP地址分成4个部分,每个部分为8位,表示成一个无符号整数(因此正号不需要出现),如10.137.17.1,是我们非常熟悉的IP地址,一个IP地址串中没有空格出现(因为要表示成一个32数字)。

现在需要你用程序来判断IP是否合法。

package com.micheal;

import java.util.Scanner;

public class HJ90 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String str = in.next();
            String[] nums = str.split("\\.", -1);
            String result = "YES";
            if (nums.length == 4) {
                for (String element : nums) {
                    if (element.length() == 0 || element.length() > 3) {
                        result = "NO";
                        break;
                    }
                    for (Character ch : element.toCharArray()) {
                        if (!Character.isDigit(ch)) {
                            result = "NO";
                            break;
                        }
                    }
                    if (element.charAt(0) == '0' && element.length() != 1) {
                        result = "NO";
                        break;
                    }
                    if (Integer.parseInt(element) > 255) {
                        result = "NO";
                        break;
                    }
                }
            } else {
                result = "NO";
            }
            System.out.println(result);
        }
    }
}

87、HJ91  走方格的方案数

请计算n*m的棋盘格子(n为横向的格子数,m为竖向的格子数)从棋盘左上角出发沿着边缘线从左上角走到右下角,总共有多少种走法,要求不能走回头路,即:只能往右和往下走,不能往左和往上走。

注:沿棋盘格之间的边缘线行走

package com.micheal;

import java.util.Scanner;

public class HJ91 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextInt()) {
            int m = sc.nextInt();
            int n = sc.nextInt();
            System.out.println(cal(m, n));
        }

    }

    private static int cal(int m, int n) {
        if (m == 1 || n == 1) {
            return m + n;
        }
        return cal(m - 1, n) + cal(m, n - 1);
    }
}

88、HJ92  在字符串中找出连续最长的数字串

输入一个字符串,返回其最长的数字子串,以及其长度。若有多个最长的数字子串,则将它们全部输出(按原字符串的相对位置)

本题含有多组样例输入。

package com.micheal;

import java.util.ArrayList;
import java.util.Scanner;

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

89、HJ93  数组分组

输入int型数组,询问该数组能否分成两组,使得两组中各元素加起来的和相等,并且,所有5的倍数必须在其中一个组中,所有3的倍数在另一个组中(不包括5的倍数),不是5的倍数也不是3的倍数能放在任意一组,可以将数组分为空数组,能满足以上条件,输出true;不满足时输出false。

package com.micheal;

import java.util.LinkedList;
import java.util.Scanner;

public class HJ93 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            LinkedList list = new LinkedList<>();
            int n = in.nextInt();
            int sum5 = 0;
            int sum3 = 0;
            int sum = 0;
            for (int i = 0; i < n; i++) {
                int cur = in.nextInt();
                if (cur % 5 == 0) {
                    sum5 += cur;
                } else if (cur % 3 == 0) {
                    sum3 += cur;
                } else {
                    list.add(cur);
                }
                sum += cur;
            }
            int target = sum / 2 - sum3;
            if (sum % 2 != 0) System.out.println("false");
            else System.out.println(helper(list, target));
        }
    }

    private static boolean helper(LinkedList list, int target) {
        return helper(0, list, target);
    }

    private static boolean helper(int l, LinkedList list, int target) {
        if (l == list.size()) return target == 0;
        return helper(l + 1, list, target - list.get(l)) || helper(l + 1, list, target);
    }
}

90、HJ94  记票统计

请实现一个计票统计系统。你会收到很多投票,其中有合法的也有不合法的,请统计每个候选人得票的数量以及不合法的票数。

(注:不合法的投票指的是投票的名字不存在n个候选人的名字中!!)

package com.micheal;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;

public class HJ94 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            Map map = new LinkedHashMap<>();
            int n = sc.nextInt();
            int invalid = 0;
            for (int i = 0; i < n; i++) {
                map.put(sc.next(), 0);
            }
            int m = sc.nextInt();
            for (int i = 0; i < m; i++) {
                String key = sc.next();
                if (map.containsKey(key)) {
                    map.put(key, map.get(key) + 1);
                } else {
                    invalid++;
                }
            }
            for (String key : map.keySet()) {
                System.out.println(key + " : " + map.get(key));
            }
            System.out.println("Invalid" + " : " + invalid);
        }
        sc.close();
    }
}

91、HJ95  人民币转换

考试题目和要点:

1、中文大写金额数字前应标明“人民币”字样。中文大写金额数字应用壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整等字样填写。

2、中文大写金额数字到“元”为止的,在“元”之后,应写“整字,如532.00应写成“人民币伍佰叁拾贰元整”。在”角“和”分“后面不写”整字。

3、阿拉伯数字中间有“0”时,中文大写要写“零”字,阿拉伯数字中间连续有几个“0”时,中文大写金额中间只写一个“零”字,如6007.14,应写成“人民币陆仟零柒元壹角肆分“。

4、10应写作“拾”,100应写作“壹佰”。例如,1010.00应写作“人民币壹仟零拾元整”,110.00应写作“人民币壹佰拾元整”

5、十万以上的数字接千不用加“零”,例如,30105000.00应写作“人民币叁仟零拾万伍仟元整”

package com.micheal;

import java.util.Scanner;

public class HJ95 {
    public static String[] ten = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
    public static String[] power = {"万", "亿"};
    public static String[] daiwei = {"元", "角", "分", "整"};

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            String[] s = in.nextLine().split("\\.");
            if (s[1].equals("00")) {
                System.out.println("人民币" + solveZheng(Double.parseDouble(s[0])) + "元整");
            } else if (s[0].equals("0")) {
                System.out.println("人民币" + solveXiao(s[1]));
            } else {
                System.out.println("人民币" + solveZheng(Double.parseDouble(s[0])) + "元" + solveXiao(s[1]));
            }
        }
    }

    public static String solveXiao(String s2) {
        StringBuilder sb = new StringBuilder();
        int jiao = Integer.parseInt(s2.substring(0, 1));
        int fen = Integer.parseInt(s2.substring(1, 2));
        if (jiao != 0) {
            sb.append(ten[jiao]);
            sb.append("角");
        }
        if (fen != 0) {
            sb.append(ten[fen]);
            sb.append("分");
        }
        return sb.toString();
    }

    public static String solveZheng(double zheng) {
        StringBuilder sb = new StringBuilder();
        int pow = 0;
        while ((int) zheng != 0) {
            if (pow != 0) {
                sb.append(power[pow - 1]);
            }
            int temp = (int) (zheng % 10000);
            int gewei = temp % 10;
            int shiwei = (temp / 10) % 10;
            int baiwei = (temp / 100) % 10;
            int qianwei = (temp / 1000) % 10;
            if (gewei != 0) {
                sb.append(ten[gewei]);
            }
            if (shiwei != 0) {
                sb.append("拾");
                if (shiwei != 1) {
                    sb.append(ten[shiwei]);
                }
            } else {
                if (gewei != 0 && (temp > 99 || (int) zheng > 10000)) {
                    sb.append(ten[0]);
                }
            }
            if (baiwei != 0) {
                sb.append("佰");
                sb.append(ten[baiwei]);
            } else {
                if (shiwei != 0 && (temp > 999 || (int) zheng > 10000)) {
                    sb.append(ten[0]);
                }
            }
            if (qianwei != 0) {
                sb.append("仟");
                sb.append(ten[qianwei]);
            } else {
                if (baiwei != 0 && (int) zheng > 10000) {
                    sb.append(ten[0]);//
                }
            }
            zheng /= 10000;
            pow++;
            if (pow > 2) {
                pow = 1;
            }
        }
        return sb.reverse().toString();
    }
}

92、HJ96  表示数字

将一个字符中所有的整数前后加上符号“*”,其他字符保持不变。连续的数字视为一个整数。

package com.micheal;

import java.util.Scanner;

public class HJ96 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String input = scanner.next();
            System.out.println(input.replaceAll("([0-9]+)", "*$1*"));
        }
    }
}

93、HJ97  记负均正

首先输入要输入的整数个数n,然后输入n个整数。输出为n个整数中负数的个数,和所有正整数的平均值,结果保留一位小数。

0即不是正整数,也不是负数,不计入计算。如果没有正数,则平均值为0。

package com.micheal;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class HJ97 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int sum = Integer.parseInt(sc.nextLine());
            String[] strs = sc.nextLine().trim().split(" ");
            List list = new ArrayList();
            for (String i : strs) {
                list.add(Integer.parseInt(i));
            }
            int count = 0;
            int total = 0;
            int n = 0;
            for (int j = 0; j < list.size(); j++) {
                if (list.get(j) > 0) {
                    count = count + list.get(j);
                    n++;
                } else if (list.get(j) < 0) {
                    total++;
                }
            }
            System.out.print(total + " " + Math.round(count * 10.0 / n) / 10.0);
            System.out.println();
        }
    }
}

94、HJ98  自动售货系统

描述

1 总体说明

考生需要模拟实现一个简单的自动售货系统,实现投币、购买商品、退币、查询库存商品及存钱盒信息的功能。

系统初始化时自动售货机中商品为6种商品,商品的单价参见1.1规格说明,存钱盒内放置1元、2元、5元、10元钱币,商品数量和钱币张数通过初始化命令设置,参见2.1 系统初始化。

1.1规格说明

1. 商品:每种商品包含商品名称、单价、数量三种属性,其中商品名不重复。考生不能修改商品名称和单价,初始化命令设置商品数量。这些信息在考试框架中进行定义,考生在实现功能代码时可直接使用。

商品 名称

单价

数量

A1 2 X
A2 3 X
A3 4 X
A4 5 X
A5 8 X
A6 6 X

2. 存钱盒信息:钱币面额、张数两种属性。初始化命令设置各种面额钱币张数。这些信息在考试框架中进行定义,考生在实现功能代码时可直接使用。

钱币面额

张数

10元

X

5元

X
2元 X
1元 X

3. 退币原则 

1) 根据系统存钱盒内钱币的 信息 ,按钱币总张数最少的原则进行退币。

2) 如果因零钱不足导致不能退币,则尽最大可能退币,以减少用户损失。

例如:假设存钱盒内只有4张2元,无其它面额钱币。如果需要退币7元,系统因零钱不足无法退币,则继续尝试退币6元,最终系统成功退币3张2元,用户损失1元钱币。

4. 投币操作说明:每次投币成功,投入的钱币面额累加到投币余额;同时,本次投入的钱币放入存钱盒中,存钱盒相应面额钱币增加。

5. 投币余额:指当前自动售货机中用户剩余的可购买商品的钱币总额;例如:投入2元面额的钱币,投币余额增加2元;购买一件价格2元的商品,投币余额减少2元;

6. 退币操作说明:退币操作需要遵守 退币原则 ;退币成功后,投币余额清零,同时扣除存钱盒相应的金额。

7. 购买商品操作说明:一次仅允许购买一件商品;购买商品成功后,自动售货机中对应商品数量减1,投币余额扣除本次购买商品的价格。

2 操作说明

命令字与第一个参数间使用一个空格分隔,多条命令采用分号隔开。考试系统会对输入命令格式进行处理,考生不需要关注输入命令格式的合法性,只需要实现命令处理函数。

2.1 系统初始化

命令格式

r A1 数量 -A2 数量 -A3 数量 -A4 数量 -A5 数量 -A6 数量 元张数 -2 元张数 -5 元张数 -10 元张数

参数名称

参数说明

类型

取值范围

A1数量

商品A1数量

整数

[0,30]

A2数量

商品A2数量

整数

[0,30]

A3数量

商品A3数量

整数

[0,30]

A4数量

商品A4数量

整数

[0,30]

A5数量

商品A5数量

整数

[0,30]

A6数量

商品A6数量

整数

[0,30]

1元张数

面额1元钱币张数

整数

[0,30]

2元张数

面额2元钱币张数

整数

[0,30]

5元张数

面额5元钱币张数

整数

[0,30]

10元张数

面额10元钱币张数

整数

[0,30]

商品和各种面额钱币取值范围只是作为初始化命令的限制,其它场景下不限制取值范围;考试框架已经实现取值范围的检查,考生不需要关注。

功能说明:设置自动售货机中商品数量和存钱盒各种面额的钱币张数;

约束说明:系统在任意阶段均可执行r初始化系统;考生不需要关注参数的合法性,不需要关注增加或缺少参数的场景;

输出说明:输出操作成功提示(执行完r命令后系统会自动输出操作结果,考生不需要再次调用输出函数),例:

命令 输出 含义
r 6-5-4-3-2-1 4-3-2-1; S001:Initialization is successful 初始化成功

2.2 投币

命令格式钱币面额

功能说明

(1) 如果投入非1元、2元、5元、10元的钱币面额(钱币面额不考虑负数、字符等非正整数的情况),输出“E002:Denomination error”;

(2) 如果存钱盒中1元和2元面额钱币总额小于本次投入的钱币面额,输出“E003:Change is not enough, pay fail”,但投入1元和2元面额钱币不受此限制。

(3) 如果自动售货机中商品全部销售完毕,投币失败。输出“E005:All the goods sold out”;

(4) 如果投币成功,输出“S002:Pay success,balance=X”;

约束说明

(1) 系统在任意阶段都可以投币;

(2) 一次投币只能投一张钱币;

(3) 同等条件下,错误码的优先级:E002 > E003 > E005;

输出说明:如果投币成功,输出“S002:Pay success,balance=X”。

例:

命令

输出

p 10;

S002:Pay success,balance=10

2.3 购买商品

命令格式商品名称

功能说明

(1) 如果购买的商品不在商品列表中,输出“E006:Goods does not exist”;

(2) 如果所购买的商品的数量为0,输出“E007:The goods sold out”;

(3) 如果投币余额小于待购买商品价格,输出“E008:Lack of balance”;

(4) 如果购买成功,输出“S003:Buy success,balance=X”;

约束说明

(1) 一次购买操作仅能购买一件商品,可以多次购买;

(2) 同等条件下,错误码的优先级:E006 > E007 > E008;

输出说明:

如果购买成功,输出“S003:Buy success,balance=X”。

例:

命令

输出

b A1;

S003:Buy success,balance=8

2.4 退币

命令格式c

功能说明

(1) 如果投币余额等于0的情况下,输出“E009:Work failure”;

(2) 如果投币余额大于0的情况下,按照 退币原则 进行“找零”,输出退币信息;

约束说明

(1) 系统在任意阶段都可以退币;

(2) 退币方式必须按照 退币原则 进行退币;

输出说明:如果退币成功,按照 退币原则 输出退币信息。

例,退5元钱币:

命令

输出

c;

1 yuan coin number=0

2 yuan coin number=0

5 yuan coin number=1

10 yuan coin number=0

2.5 查询

命令格式q 查询类别

功能说明

(1) 查询自动售货机中商品信息,包含商品名称、单价、数量。 根据商品数量从大到小进行排序;商品数量相同时,按照商品名称的先后顺序进行排序 

例如:A1的商品名称先于A2的商品名称,A2的商品名称先于A3的商品名称。

(2) 查询存钱盒信息,包含各种面额钱币的张数;

(3) 查询类别如下表所示:

查询类别

查询内容

0

查询商品信息

1 查询存钱盒信息

如果“查询类别”参数错误,输出“E010:Parameter error”。“查询类别”参数错误时,不进行下面的处理;

输出说明

“查询类别”为0时,输出自动售货机中所有商品信息(商品名称单价数量)例:

命令

输出

q 0;

A1 2 6

A2 3 5

A3 4 4

A4 5 3

A5 8 2

A6 6 0

“查询类别”为1时,输出存钱盒信息(各种面额钱币的张数),格式固定。例:

命令

输出

q 1;

1 yuan coin number=4

2 yuan coin number=3

5 yuan coin number=2

10 yuan coin number=1

package com.micheal;

import java.util.ArrayList;
import java.util.Scanner;

public class HJ98 {
    static ArrayList goods = new ArrayList();
    static ArrayList moneys = new ArrayList();
    static int goodTotal;
    static int moneyTotal;

    public static void main(String[] args) {
        goods.add(new Good("A1", 2));
        goods.add(new Good("A2", 3));
        goods.add(new Good("A3", 4));
        goods.add(new Good("A4", 5));
        goods.add(new Good("A5", 8));
        goods.add(new Good("A6", 6));

        moneys.add(new Money(1));
        moneys.add(new Money(2));
        moneys.add(new Money(5));
        moneys.add(new Money(10));
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String str = sc.nextLine();
            String[] arr = str.split(";");
            for (int i = 0; i < arr.length; i++) {
                if (arr[i].contains("r")) {
                    rStep(arr[i]);
                } else if (arr[i].contains("p")) {
                    pStep(arr[i]);
                } else if (arr[i].contains("b")) {
                    bStep(arr[i]);
                } else if (arr[i].contains("c")) {
                    cStep(arr[i]);
                } else if (arr[i].contains("q")) {
                    qStep(arr[i]);
                }
            }
        }

    }

    public static void rStep(String str) {
        String[] msg = str.split(" ");
        String[] goodNum = msg[1].split("-");
        for (int i = 0; i < goodNum.length; i++) {
            int count = Integer.parseInt(goodNum[i]);
            goods.get(i).count = count;
            goodTotal += count;
        }
        String[] moneyNum = msg[2].split("-");
        for (int i = 0; i < moneyNum.length; i++) {
            moneys.get(i).count = Integer.parseInt(moneyNum[i]);
        }
        moneyTotal = 0;//每次初始化,投币余额必须赋0
        System.out.println("S001:Initialization is successful");
    }

    public static void pStep(String str) {
        String[] msg = str.split(" ");
        int num = Integer.parseInt(msg[1]);
        if (num != 1 && num != 2 && num != 5 && num != 10) {
            System.out.println("E002:Denomination error");
            return;
        }
        if (num > 2 && moneys.get(0).count + moneys.get(1).count * 2 < num) {
            System.out.println("E003:Change is not enough, pay fail");
            return;
        }
        if (goodTotal == 0) {
            System.out.println("E005:All the goods sold out");
            return;
        }
        moneyTotal += num;
        if (num == 1) {
            moneys.get(0).count += 1;
        } else if (num == 2) {
            moneys.get(1).count += 1;
        } else if (num == 5) {
            moneys.get(2).count += 1;
        } else if (num == 10) {
            moneys.get(3).count += 1;
        }
        System.out.println("S002:Pay success,balance=" + moneyTotal);
    }

    public static void bStep(String str) {
        String[] msg = str.split(" ");
        String name = msg[1];
        boolean existed = false;
        Good good = null;
        for (int i = 0; i < goods.size(); i++) {
            if (goods.get(i).name.equals(name)) {
                existed = true;
                good = goods.get(i);
                break;
            }
        }
        if (!existed) {
            System.out.println("E006:Goods does not exist");
            return;
        }
        if (goodTotal == 0) {
            System.out.println("E007:The goods sold out");
            return;
        }
        if (moneyTotal < good.price) {
            System.out.println("E008:Lack of balance");
            return;
        }
        moneyTotal -= good.price;
        System.out.println("S003:Buy success,balance=" + moneyTotal);
    }

    public static void cStep(String str) {
        if (moneyTotal == 0) {
            System.out.println("E009:Work failure");
            return;
        }
        int tenNum = 0;
        int fiveNum = 0;
        int secNum = 0;
        int oneNum = 0;
        while (moneyTotal >= 10 && moneys.get(3).count > 0) {
            moneyTotal -= 10;
            moneys.get(3).count -= 1;
            tenNum++;
        }
        while (moneyTotal >= 5 && moneys.get(2).count > 0) {
            moneyTotal -= 5;
            moneys.get(2).count -= 1;
            fiveNum++;
        }
        while (moneyTotal >= 2 && moneys.get(1).count > 0) {
            moneyTotal -= 2;
            moneys.get(1).count -= 1;
            secNum++;
        }
        while (moneyTotal >= 1 && moneys.get(0).count > 0) {
            moneyTotal -= 1;
            moneys.get(0).count -= 1;
            oneNum++;
        }
        moneyTotal = 0;
        System.out.println("1 yuan coin number=" + oneNum);
        System.out.println("2 yuan coin number=" + secNum);
        System.out.println("5 yuan coin number=" + fiveNum);
        System.out.println("10 yuan coin number=" + tenNum);
    }

    public static void qStep(String str) {
        if (!str.contains(" ")) {
            System.out.println("E010:Parameter error");
            return;
        }
        String[] arr = str.split(" ");
        int num = Integer.parseInt(arr[1]);
        if (num < 0 || num > 1) {
            System.out.println("E010:Parameter error");
            return;
        }
        if (num == 0) {
            Good good = null;
            for (int i = 0; i < goods.size(); i++) {
                good = goods.get(i);
                System.out.println(good.name + " " + good.price + " " + good.count);
            }
        } else {
            Money money = null;
            for (int i = 0; i < moneys.size(); i++) {
                money = moneys.get(i);
                System.out.println(money.id + " yuan coin number=" + money.count);
            }
        }
    }
}

class Good {
    String name;
    int price;
    int count;

    public Good(String name, int price) {
        this.name = name;
        this.price = price;
    }
}

class Money {
    int id;
    int count;

    public Money(int id) {
        this.id = id;
    }
}

 95、HJ99  自守数

自守数是指一个数的平方的尾数等于该数自身的自然数。例如:25^2 = 625,76^2 = 5776,9376^2 = 87909376。请求出n(包括n)以内的自守数的个数

package com.micheal;

import java.util.Scanner;

public class HJ99 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            int count = 0;
            for (int i = 0; i <= n; i++) {
                int sum = i * i;
                String s1 = String.valueOf(i);
                String s2 = String.valueOf(sum);
                if (s2.substring(s2.length() - s1.length()).equals(s1)) {
                    count++;
                }
            }
            System.out.println(count);
        }
    }
}

96、HJ100  等差数列

等差数列 2,5,8,11,14。。。。

(从 2 开始的 3 为公差的等差数列)

输出求等差数列前n项和

package com.micheal;

import java.util.Scanner;

public class HJ100 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int length = sc.nextInt(); // n
            int first = 2, last = 3 * length - 1; // a1, an
            System.out.println((first + last) * length / 2);
        }
        sc.close();
    }
}

97、HJ101  输入整型数组和排序标识,对其元素按照升序或降序进行排序

输入整型数组和排序标识,对其元素按照升序或降序进行排序

package com.micheal;

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

public class HJ101 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int arrCount = sc.nextInt();
            Integer[] arr = new Integer[arrCount];
            for (int i = 0; i < arrCount; i++) {
                arr[i] = sc.nextInt();
            }
            int flagSort = sc.nextInt();
            if (flagSort == 0) {
                Arrays.sort(arr, new Comparator() {
                    public int compare(Integer o1, Integer o2) {
                        return o1 - o2;
                    }
                });
            }
            if (flagSort == 1) {
                Arrays.sort(arr, new Comparator() {
                    public int compare(Integer o1, Integer o2) {
                        return o2 - o1;
                    }
                });
            }
            for (Integer m : arr) {
                System.out.print(m + " ");
            }
            break;
        }
        System.out.println();
    }
}

98、HJ102  字符统计

输入一个只包含小写英文字母和数字的字符串,按照不同字符统计个数由多到少输出统计结果,如果统计的个数相同,则按照ASCII码由小到大排序输出。

package com.micheal;

import java.util.Scanner;

public class HJ102 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String s = sc.nextLine();
            char[] carr = s.toCharArray();
            int[] arr = new int[129];
            StringBuilder sb = new StringBuilder();
            for (char c : carr) {
                arr[(int) c]++;
            }
            int max = 0;
            for (int i = 0; i < arr.length; i++) {
                if (max < arr[i]) {
                    max = arr[i];
                }
            }
            while (max != 0) {
                for (int i = 0; i < arr.length; i++) {
                    if (arr[i] == max) {
                        sb.append((char) i);
                    }
                }
                max--;
            }
            System.out.println(sb.toString());
        }
    }
}

99、HJ103  Redraiment的走法

Redraiment是走梅花桩的高手。Redraiment可以选择任意一个起点,从前到后,但只能从低处往高处的桩子走。他希望走的步数最多,你能替Redraiment研究他最多走的步数吗?

package com.micheal;

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

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

100、HJ105  记负均正II

输入 n 个整型数,统计其中的负数个数并求所有非负数的平均值,结果保留一位小数,如果没有非负数,则平均值为0

本题有多组输入数据,输入到文件末尾。

package com.micheal;

import java.util.Scanner;

public class HJ105 {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        float count1 = 0;
        int count2 = 0;
        float sum = 0;
        while (sc.hasNextInt()){
            int cur = sc.nextInt();
            if (cur >= 0){
                count1++;
                sum += cur;
            }else{
                count2++;
            }
        }
        System.out.println(count2);
        System.out.printf("%.1f\n", sum/count1);
    }
}

101、HJ106  字符逆序

将一个字符串str的内容颠倒过来,并输出。

package com.micheal;

import java.util.Scanner;

public class HJ106 {
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        String input = scan.nextLine();
        StringBuilder res = new StringBuilder(input);
        System.out.println(res.reverse());
    }
}

102、HJ107  求解立方根

计算一个浮点数的立方根,不使用库函数。

保留一位小数。

package com.micheal;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class HJ107 {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        double num = Double.valueOf(bf.readLine());
        double x = Dichotomy(num);
        System.out.printf("%.1f",x);
    }
    public static double Dichotomy(double num) {
        double right , left, mid = 0.0;
        right = Math.max(1.0,num);
        left = Math.min(-1.0,num);
        while (right - left > 0.001) {
            mid = (left + right) / 2;
            if (mid * mid * mid > num) {
                right = mid;
            }
            else if (mid * mid * mid < num) {
                left = mid;
            } else {
                return mid;
            }
        }
        return right;
    }
}

103、HJ108  求最小公倍数

正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数。

package com.micheal;

import java.util.Scanner;

public class HJ108 {
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        int a=in.nextInt();
        int b=in.nextInt();
        System.out.println(a*b/gcd(a,b));
    }

    private static int gcd(int a, int b) {
        return b==0?a:gcd(b,a%b);
    }
}

你可能感兴趣的:(算法,java,开发语言)