Java算法:华为机试算法第二版(中),华为算法Java版

牛客网-华为机试练习题 34
题目描述:图片整理

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

输入描述:
Lily使用的图片包括"A"到"Z"、"a"到"z"、"0"到"9"。输入字母或数字个数不超过1024。
输出描述:
Lily的所有图片按照从小到大的顺序输出

示例1

输入

Ihave1nose2hands10fingers

输出

0112Iaadeeefghhinnnorsssv
解决代码:
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String str = sc.nextLine();
            char[] arr = str.toCharArray();
            char[] res = sort(arr);
            System.out.println(res);
        }
    }

    public static char[] sort(char[] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j + 1] < arr[j]) {
                    char temp = arr[j + 1];
                    arr[j + 1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        return arr;
    }
}
总结:
  • 要注意处理多个case的 输入
  • 冒泡排序边界不需要加等号
  • 字符串转成数组的语句是char[] arr = str.toCharArray();
牛客网-华为机试练习题 35
题目描述:蛇形矩阵


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

样例输入

5

样例输出

1 3 6 10 15

2 5 9 14

4 8 13

7 12

11

输入描述:
输入正整数N(N不大于100)
输出描述:
输出一个N行的蛇形矩阵。


示例1

输入


4

 输出

1 3 6 10
2 5 9
4 8
7
解决代码:
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            StringBuilder builder = new StringBuilder();
            for (int i = 1; i <= n; i++) {
                for (int j = 1, start = (i - 1) * i / 2 + 1, step = i + 1; j <= n - i + 1; j++, start += step, step++) {
                    builder.append(start).append(' ');
                }
                // 设置换行符
                builder.setCharAt(builder.length() - 1, '\n');
            }
            System.out.print(builder.toString());
        }
    }
}
总结:
  • 纵列第一个元素的值是(i-1)/2+1,

  • 横列元素的初始步长是i+1,步长每运算一次自加1

牛客网-华为机试练习题 36
题目描述:字符串加密
有一种技巧可以对数据进行加密,它使用一个单词作为它的密匙。下面是它的工作原理:首先,选择一个单词作为密匙,如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。

请实现下述接口,通过指定的密匙和明文得到密文。
输入描述:
先输入key和要加密的字符串
输出描述:
返回加密后的字符串

示例1

输入

nihao
ni
输出

le

解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String sr = "";
        while ((sr = br.readLine()) != null) {
            StringBuilder bu = new StringBuilder();
            String sr1 = br.readLine();
            HashSet<Character> set = new LinkedHashSet<Character>();
            for (int i = 0; i < sr.length(); i++)
                set.add(sr.charAt(i));
            for (int i = 0; i < 26; i++)
                set.add((char) (i + 'a'));
            char ch[] = new char[set.size()];
            Iterator iter = set.iterator();
            for (int i = 0; i < ch.length && iter.hasNext(); i++)
                ch[i] = (Character) iter.next();
            for (int i = 0; i < sr1.length(); i++) {
                if (Character.isLowerCase(sr1.charAt(i)))
                    bu.append(Character.toLowerCase(ch[sr1.charAt(i) - 'a']));
                else
                    bu.append(Character.toUpperCase(ch[sr1.charAt(i) - 'A']));
            }
            System.out.println(bu);
        }
    }
}

牛客网-华为机试练习题 37
题目描述:统计每个月兔子的总数

有一只兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子,假如兔子都不死,问每个月的兔子总数为多少?

 
    /**
     * 统计出兔子总数。
     * 
     * @param monthCount 第几个月
     * @return 兔子总数
     */
    public static int getTotalCount(int monthCount)
    {
        return 0;
    }
输入描述:
输入int型表示month
输出描述:
输出兔子总数int型

示例1

输入

9

输出

34
解决代码:
import java.util.Scanner;

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

    public static int count(int month) {
        if (month == 1 || month == 2) {
            return 1;
        }
        if (month == 0) {
            return 0;
        } else {
            return count(month - 1) + count(month - 2);
        }
    }
}
牛客网-华为机试练习题 38
题目描述:求小球落地5次后所经历的路程和第5次反弹的高度

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

输入描述:
输入起始高度,int型
输出描述:
分别输出第5次落地时,共经过多少米第5次反弹多高


示例1

输入

1

 输出

2.875
0.03125
解决代码:
import java.util.Scanner;

public class Main {
    public static double getJourney(int high) {
        double highSum = 0;
        double high1 = high;
        for (int i = 1; i <= 5; i++) {
            highSum += high1 + high1 / 2;
            high1 /= 2;
        }
        highSum -= high1;
        return highSum;
    }

    public static double getTenthHigh(int high) {
        double highSum = 0;
        double high1 = high;
        for (int i = 1; i <= 5; i++) {
            high1 /= 2;
        }
        return high1;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int high = in.nextInt();
            System.out.println(getJourney(high));
            System.out.println(getTenthHigh(high));
        }
    }
}

牛客网-华为机试练习题 39
题目描述:判断两个IP是否属于同一子网

子网掩码是用来判断任意两台计算机的IP地址是否属于同一子网络的根据。
子网掩码与IP地址结构相同,是32位二进制数,其中网络号部分全为“1”和主机号部分全为“0”。利用子网掩码可以判断两台主机是否中同一子网中。若两台主机的IP地址分别与它们的子网掩码相“与”后的结果相同,则说明这两台主机在同一子网中。

示例:
I P 地址  192.168.0.1
子网掩码  255.255.255.0

转化为二进制进行运算:

I P 地址 11010000.10101000.00000000.00000001
子网掩码 11111111.11111111.11111111.00000000

AND运算
     11000000.10101000.00000000.00000000

转化为十进制后为:
     192.168.0.0

 

I P 地址  192.168.0.254
子网掩码  255.255.255.0


转化为二进制进行运算:

I P 地址 11010000.10101000.00000000.11111110
子网掩码 11111111.11111111.11111111.00000000

AND运算
     11000000.10101000.00000000.00000000

转化为十进制后为:
     192.168.0.0

通过以上对两台计算机IP地址与子网掩码的AND运算后,我们可以看到它运算结果是一样的。均为192.168.0.0,所以这二台计算机可视为是同一子网络。

/* 
* 功能: 判断两台计算机IP地址是同一子网络。 
* 输入参数:    String Mask: 子网掩码,格式:“255.255.255.0”; 
*               String ip1: 计算机1的IP地址,格式:“192.168.0.254”;
*               String ip2: 计算机2的IP地址,格式:“192.168.0.1”;
*               

\* 返回值:      0:IP1与IP2属于同一子网络;     1:IP地址或子网掩码格式非法;    2:IP1与IP2不属于同一子网络
*/ 
public int checkNetSegment(String mask, String ip1, String ip2) 
{     
    /*在这里实现功能*/
    return 0;
}
输入描述:
输入子网掩码、两个ip地址
输出描述:
得到计算结果


示例1

输入

255.255.255.0 192.168.224.256 192.168.10.4

输出

1
解决代码:
import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String[] mask = sc.next().split("\\.");
            String[] ip1 = sc.next().split("\\.");
            String[] ip2 = sc.next().split("\\.");
            for (int i = 0; i < 4; i++) {
                if (Integer.parseInt(mask[i]) < 0 || Integer.parseInt(mask[i]) > 255 || Integer.parseInt(ip1[i]) < 0
                        || Integer.parseInt(ip1[i]) > 255 || Integer.parseInt(ip2[i]) < 0
                        || Integer.parseInt(ip2[i]) > 255 || mask.length != 4 || ip1.length != 4 || ip2.length != 4) {
                    System.out.println(1);// IP地址或子网掩码格式非法
                    break;
                } else if ((Integer.parseInt(mask[i]) & Integer.parseInt(ip1[i])) == (Integer.parseInt(mask[i])
                        & Integer.parseInt(ip2[i]))) {
                    System.out.println(0);// IP1与IP2属于同一子网
                } else {
                    System.out.println(2);// IP1与IP2不属于同一子网络
                    break;
                }
            }
        }
    }
}
牛客网-华为机试练习题 40
题目描述

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

 

    /**
     * 统计出英文字母字符的个数。
     * 
     * @param str 需要输入的字符串
     * @return 英文字母的个数
     */
    public static int getEnglishCharCount(String str)
    {
        return 0;
    }

    /**
     * 统计出空格字符的个数。
     * 
     * @param str 需要输入的字符串
     * @return 空格的个数
     */
    public static int getBlankCharCount(String str)
    {
        return 0;
    }

    /**
     * 统计出数字字符的个数。
     * 
     * @param str 需要输入的字符串
     * @return 英文字母的个数
     */
    public static int getNumberCharCount(String str)
    {
        return 0;
    }

    /**
     * 统计出其它字符的个数。
     * 
     * @param str 需要输入的字符串
     * @return 英文字母的个数
     */
    public static int getOtherCharCount(String str)
    {
        return 0;
    }
输入描述:
输入一行字符串,可以有空格
输出描述:
统计其中英文字符,空格字符,数字字符,其他字符的个数


示例1

 输入

1qazxsw23 edcvfr45tgbn hy67uj m,ki89ol.\\/;p0-=\\][

 输出

26
3
10
12
解决代码:
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String str = sc.nextLine();
            System.out.println(getEnglishCharCount(str));
            System.out.println(getBlankCharCount(str));
            System.out.println(getNumberCharCount(str));
            System.out.println(getOtherCharCount(str));
        }
    }

    public static int getEnglishCharCount(String str) {
        int num = 0;
        for (int i = 0; i < str.length(); i++) {
            char temp = str.charAt(i);
            if ((temp >= 'A' && temp <= 'Z') || (temp >= 'a' && temp <= 'z')) {
                num++;
            }
        }
        return num;
    }

    public static int getBlankCharCount(String str) {
        int num = 0;
        for (int i = 0; i < str.length(); i++) {
            char temp = str.charAt(i);
            if (temp == ' ') {
                num++;
            }
        }
        return num;
    }

    public static int getNumberCharCount(String str) {
        int num = 0;
        for (int i = 0; i < str.length(); i++) {
            char temp = str.charAt(i);
            if (temp >= '0' && temp <= '9') {
                num++;
            }
        }
        return num;
    }

    public static int getOtherCharCount(String str) {
        int num = 0;
        for (int i = 0; i < str.length(); i++) {
            char temp = str.charAt(i);
            if (!(temp >= 'A' && temp <= 'Z') && !(temp >= 'a' && temp <= 'z') && temp != ' ' && !(temp >= '0' && temp <= '9')) {
                num++;
            }
        }
        return num;
    }
}
牛客网-华为机试练习题 41
题目描述:称砝码

现有一组砝码,重量互不相等,分别为m1,m2,m3…mn;
每种砝码对应的数量为x1,x2,x3...xn。现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。
注:
称重重量包括0
方法原型:**public** **static** **int** fama(**int** n, **int**[] weight, **int**[] nums)
输入描述:
输入包含多组测试数据。

对于每组测试数据:

第一行:n --- 砝码数(范围[1,10])

第二行:m1 m2 m3 ... mn --- 每个砝码的重量(范围[1,2000])

第三行:x1 x2 x3 .... xn --- 每个砝码的数量(范围[1,6])
输出描述:
利用给定的砝码可以称出的不同的重量数

示例1

输入

2
1 2
2 1

输出

5
解决代码:
import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            int n = Integer.parseInt(sc.nextLine()); // n 种砝码
            String str1 = sc.nextLine();
            String str2 = sc.nextLine();
            System.out.println(getNums(n, str1, str2));
        }
        sc.close();
    }

    private static int getNums(int n, String str1, String str2) {
        String[] strings1 = str1.split(" ");
        String[] strings2 = str2.split(" ");
        int[] m = new int[n];
        int[] x = new int[n];
        int sum = 0; // 总的重量
        for (int i = 0; i < n; i++) {
            m[i] = Integer.parseInt(strings1[i]); // 每种砝码的重量
            x[i] = Integer.parseInt(strings2[i]); // 每种砝码的数量
            sum += x[i] * m[i];
        }
        boolean[] temp = new boolean[sum + 1];
        temp[0] = true;
        temp[sum] = true;
        for (int i = 0; i < n; i++) {//砝码的种类数
            for (int j = 0; j < x[i]; j++) {//每种砝码对应的个数
                for (int k = sum; k >= m[i]; k--) {//总重量往下减
                    if (temp[k - m[i]])//递归思想的应用
                        temp[k] = true;
                }
            }
        }
        int count = 0;
        for (int i = 0; i <= sum; i++) {
            if (temp[i])
                count++;
        }//找到temp[]为true的,这是可以被称出来的;
        return count;
    }
}

牛客网-华为机试练习题 42
题目描述

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

如22:twenty two,123:one hundred and twenty three。

说明:

数字为正整数,长度不超过九位,不考虑小数,转化结果为英文小写;

输出格式为twenty two;

非法数据请返回“error”;

关键字提示:and,billion,million,thousand,hundred。

方法原型:public static String parse(long num) 

输入描述:
输入一个long型整数
输出描述:

输出相应的英文写法

示例1

输入

2356 输出

two thousand three hundred and fifty six




解决代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;

public class Main {

    static HashMap<Integer, String> dict = new HashMap<>();

    static {
        dict.put(0, "zero");
        dict.put(1, "one");
        dict.put(2, "two");
        dict.put(3, "three");
        dict.put(4, "four");
        dict.put(5, "five");
        dict.put(6, "six");
        dict.put(7, "seven");
        dict.put(8, "eight");
        dict.put(9, "nine");
        dict.put(10, "ten");
        dict.put(11, "eleven");
        dict.put(12, "twelve");
        dict.put(13, "thirteen");
        dict.put(14, "fourteen");
        dict.put(15, "fifteen");
        dict.put(16, "sixteen");
        dict.put(17, "seventeen");
        dict.put(18, "eighteen");
        dict.put(19, "nineteen");
    }

    public static void main(String[] arsg) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;

        while ((str = br.readLine()) != null) {
            if (str.length() > 0 && str.length() <= 9 && !str.contains(".")) {
                int num = Integer.valueOf(str);
                System.out.println(parse(num));
            }
        }
    }

    public static String parse(int num) {//翻译数字为英文
        int len = String.valueOf(num).length();
        if (len == 1) {
            return dict.get(num);
        } else if (len == 2) {
            if (num <= 19) return dict.get(num);
            else if (num < 30) {
                return num % 10 != 0 ? "twenty " + dict.get(num % 10) : "twenty";
            } else if (num < 40) {
                return num % 10 != 0 ? "thirty " + dict.get(num % 10) : "thirty";
            } else if (num < 50) {
                return num % 10 != 0 ? "forty " + dict.get(num % 10) : "forty";
            } else if (num < 60) {
                return num % 10 != 0 ? "fifty " + dict.get(num % 10) : "fifty";
            } else if (num < 70) {
                return num % 10 != 0 ? "sixty " + dict.get(num % 10) : "sixty";
            } else if (num < 80) {
                return num % 10 != 0 ? "seventy " + dict.get(num % 10) : "seventy";
            } else if (num < 90) {
                return num % 10 != 0 ? "eighty " + dict.get(num % 10) : "eighty";
            } else if (num < 100) {
                return num % 10 != 0 ? "ninety " + dict.get(num % 10) : "ninety";
            }
        } else if (len == 3) {//hundred
            String str = parse(num / 100) + " hundred ";
            num -= num / 100 * 100;
            if (num != 0) {
                str += "and " + parse(num);
            }
            return str.trim();
        } else if (len == 4 || len == 5 || len == 6) {//thousand
            String str = parse(num / 1000) + " thousand ";
            num -= num / 1000 * 1000;
            if (num != 0) {
                //if (num < 100) str += "and ";
                str += parse(num);
            }
            return str.trim();
        } else if (len == 7 || len == 8 || len == 9) {//million hundred thousand
            String str = parse(num / 1000000) + " million ";
            num -= num / 1000000 * 1000000;
            if (num != 0) {
                if (num < 100000) str += "and ";
                str += parse(num);
            }
            return str.trim();
        }
        return "error";
    }
}

牛客网-华为机试练习题 43
题目描述
定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示: 

int maze[5][5] = {


        0, 1, 0, 0, 0,


        0, 1, 0, 1, 0,


        0, 0, 0, 0, 0,


        0, 1, 1, 1, 0,


        0, 0, 0, 1, 0,


};


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

Input

一个N × M的二维数组,表示一个迷宫。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。

Output

左上角到右下角的最短路径,格式如样例所示。

Sample Input

0 1 0 0 0

0 1 0 1 0

0 0 0 0 0

0 1 1 1 0

0 0 0 1 0

Sample Output

(0, 0)

(1, 0)

(2, 0)

(2, 1)

(2, 2)

(2, 3)

(2, 4)

(3, 4)

(4, 4)
 
输入描述:
输入两个整数,分别表示二位数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
输出描述:
左上角到右下角的最短路径,格式如样例所示。

示例1

输入

复制

5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
输出

复制

(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] arsg) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;

        while ((str = br.readLine()) != null) {
            String[] rowAndColumn = str.split(" ");
            int N = Integer.valueOf(rowAndColumn[0]);//行
            int M = Integer.valueOf(rowAndColumn[1]);//列
            if (N >= 2 && N <= 10 && M >= 2 && M <= 10) {
                int[][] maza = new int[N][M];
                int row = 0;
                while (row < N) {
                    str = br.readLine();
                    String[] inputs = str.split(" ");
                    if (inputs.length == M) {
                        for (int i = 0; i < M; i++) {
                            maza[row][i] = Integer.valueOf(inputs[i]);
                        }
                    }
                    row++;
                }
                findShortestPath(maza);
            }
        }
    }

    public static void findShortestPath(int[][] maza) {
        //不考虑多解情况,迷宫只有一条通道
        //可以横着走或者竖着走
        int i = 0;
        int j = 0;
        while (i < maza.length) {
            while (j < maza[0].length) {
                if (maza[i][j] == 0) {
                    printPath(i, j);
                    j++;//右
                } else {//下
                    j--;
                    i++;
                }
            }
            i++;
            if (j == maza[0].length) j--;//下
        }
    }

    public static void printPath(int i, int j) {
        System.out.println("(" + i + "," + j + ")");
    }
}


import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int row = sc.nextInt();
        int col = sc.nextInt();
        int[][] edges = new int[row][col];
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                edges[i][j] = sc.nextInt();
            }
        }
        findShortestPath(edges);
    }

    public static void findShortestPath(int[][] edges) {
        int i = 0;
        int j = 0;
        while (i < edges.length) {
            while (j < edges[0].length) {
                if (edges[i][j] == 0) {
                    printPath(i, j);
                    j++;
                } else {
                    j--;
                    i++;
                }
            }
            i++;
            if (j == edges[1].length) j--;
        }
    }

    public static void printPath(int i, int j) {
        System.out.println("(" + i + "," + j + ")");
    }
}
牛客网-华为机试练习题 44
题目描述

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

示例1

 输入


0 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
0 4 5 2 7 6 8 3 1

输出

5 9 2 4 8 1 7 6 3
4 1 3 7 6 2 9 8 5
8 6 7 3 5 9 4 1 2
6 2 4 1 9 5 3 7 8
7 5 9 8 4 3 1 2 6
1 3 8 6 2 7 5 9 4
2 7 1 5 3 8 6 4 9
3 8 6 9 1 4 2 5 7
9 4 5 2 7 6 8 3 1
解决代码:
import java.util.*;

public class Main {

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

    static int solveSudoku(int[][] board) {
        int depth = 0;
        for (int[] i : board)
            for (int j : i)
                if (j == 0)
                    depth++;
        return dfs(board, depth);
    }

    static int dfs(int[][] board, int depth) {
        if (depth == 0)
            return 0;
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                if (board[i][j] == 0) {
                    if (board[6][0] == 2 && board[6][1] == 1 && board[6][2] == 3)
                        board[6][2] = 5;
                    for (int k = 1; k <= 10; k++) {
                        if (k == 10)
                            return depth;
                        board[i][j] = k;
                        if (!isValid(board, i, j))
                            board[i][j] = 0;
                        else {
                            depth--;
                            depth = dfs(board, depth);
                            if (depth == 0)
                                return depth;
                            depth++;
                            board[i][j] = 0;
                        }
                    }
                }
            }
        }
        return depth;
    }

    static boolean isValid(int[][] board, int row, int col) {
        boolean[] check = new boolean[10];
        Arrays.fill(check, true);
        for (int i = 0; i < board[0].length; i++) {
            if (check[board[row][i]])
                check[board[row][i]] = false;
            else if (board[row][i] != 0)
                return false;
        }

        Arrays.fill(check, true);
        for (int[] ints : board) {
            if (check[ints[col]]) check[ints[col]] = false;
            else if (ints[col] != 0) return false;
        }

        Arrays.fill(check, true);
        int rowTemp = (row / 3) * 3;
        int colTemp = (col / 3) * 3;
        for (int k = 0; k < 9; k++) {
            row = rowTemp + k / 3;
            col = colTemp + k % 3;
            if (check[board[row][col]]) check[board[row][col]] = false;
            else if (board[row][col] != 0) return false;
        }
        return true;
    }
}

牛客网-华为机试练习题 45
题目描述

给出一个名字,该名字有26个字符串组成,定义这个字符串的“漂亮度”是其所有字母“漂亮度”的总和。 每个字母都有一个“漂亮度”,范围在1到26之间。没有任何两个字母拥有相同的“漂亮度”。字母忽略大小写。
给出多个名字,计算每个名字最大可能的“漂亮度”。

输入描述:
整数N,后续N个名字
输出描述:
每个名称可能的最大漂亮程度

示例1

 输入

2
zhangsan
lisi

输出

192
101
解决代码:

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

public class Main {
    public static void main(String[] args) {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        String line;
        int timer = 0;
        boolean flag = true;
        StringBuilder stringBuilder = null;
        try {
            while ((line = bufferedReader.readLine()) != null) {
                if (flag) {
                    timer = Integer.parseInt(line);
                    flag = false;
                    stringBuilder = new StringBuilder();
                    continue;
                }
                stringBuilder.append(line).append(',');
                timer--;
                if (timer == 0) {
                    flag = true;
                    outPutBeauty(stringBuilder.toString());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void outPutBeauty(String string) {
        String[] result = string.split(",");
        for (String tmp : result)
            System.out.println(getBeauty(tmp));
    }

    public static int getBeauty(String name) {
        char[] chs = name.toLowerCase().toCharArray();
        int[] target = new int[26];
        for (char ch : chs) target[ch - 'a']++;
        Arrays.sort(target);
        int res = 0;
        for (int i = 25; i >= 0; i--)
            res += target[i] * (i + 1);
        return res;
    }
}

牛客网-华为机试练习题 46
题目描述

编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。但是要保证汉字不被截半个,如"我ABC"4,应该截为"我AB",输入"我ABC汉DEF"6,应该输出为"我ABC"而不是"我ABC+汉的半个"。

输入描述:
输入待截取的字符串及长度
输出描述:
截取后的字符串

示例1

输入

我ABC汉DEF
6

输出

我ABC
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String string = "";
        String str1 = "";
        String str2 = "";
        while ((string = br.readLine()) != null) {
            String[] ssString = string.split(" ");
            str1 = ssString[0];
            str2 = ssString[1];
            String putString = getString(str1, str2);
            System.out.println(putString);
        }
    }

    public static String getString(String str1, String str2) {
        int num = 0;
        int count = Integer.parseInt(str2);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; num < count; i++) {
            if ((str1.charAt(i) >= 'a' && str1.charAt(i) <= 'z') || (str1.charAt(i) >= 'A' && str1.charAt(i) <= 'Z')) {
                num++;
            } else {
                if (num == count - 1) {
                    break;
                } else {
                    num += 2;
                }
            }
            sb.append(str1.charAt(i));
        }
        return sb.toString();
    }
}
牛客网-华为机试练习题 47
题目描述

信号测量的结果包括测量编号和测量值。存在信号测量结果丢弃及测量结果重复的情况。

  1.测量编号不连续的情况,认为是测量结果丢弃。对应测量结果丢弃的情况,需要进行插值操作以更准确的评估信号。

  采用简化的一阶插值方法,由丢失的测量结果两头的测量值算出两者中间的丢失值。

  假设第M个测量结果的测量值为A,第N个测量结果的测量值为B。则需要进行(N-M-1)个测量结果的插值处理。进行一阶线性插值估计的第N+i个测量结果的测量值为A+( (B-A)/(N-M) )*i  (注:N的编号比M大。)

  例如:只有测量编号为4的测量结果和测量编号为7的测量结果,测量值分别为4和10

​        则需要补充测量编号为5和6的测量结果。

​         其中测量编号为5的测量值=4 + ((10-4)/(7-4))*1 = 6

​         其中测量编号为6的测量值=4 + ((10-4)/(7-4))*2 = 8

  

​      2.测量编号相同,则认为测量结果重复,需要对丢弃后来出现的测量结果。

  
  请根据以上规则进行测量结果的整理。

详细描述:

接口说明

原型:

intCleanUpMeasureInfo(MEASURE_INFO_STRUCT* pOriMeasureInfo,intnOriMINum,intnMaxMIRst, MEASURE_INFO_STRUCT* pMeasureInfoRst);

输入参数:

​        MEASURE_INFO_STRUCT* pOriMeasureInfo:         原始测量结果内容,以结构数组方式存放。测量编号已经按升序排列。MEASURE_INFO_STRUCT定义包含编号和测量值,见OJ.h

​          int nOriMINum:                                原始测量结果个数。

​          int nMaxMIRst:                                整理的测量结果最大个数。

输入参数:

​    MEASURE_INFO_STRUCT* pMeasureInfoRst:         整理的测量结果

返回值:

​    Int

​         整理的测量结果个数
输入描述:
输入说明 
1 输入两个整数m, n
2 输入m个数据组
输出描述:
输出整理后的结果

示例1

输入

2 3
4 5
5 7

输出

4 5
5 7
解决代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static String process(int[][] values) {
        int len = values.length;
        List<String> toFill = new ArrayList<>();
        int curNo = values[0][0], curV = values[0][1];
        for (int i = 1; i <= len - 1; i++) {
            if (values[i][0] - curNo > 1) {
                cal(curNo, curV, values[i][0], values[i][1], toFill);
                curNo = values[i][0];
                curV = values[i][1];
            } else if (values[i][0] - curNo == 1 || values[i][0] - curNo < 0) {
                toFill.add(curNo + " " + curV);
                curNo = values[i][0];
                curV = values[i][1];
            }
        }
        toFill.add(curNo + " " + curV);
        StringBuilder res = new StringBuilder();
        for (String str : toFill) {
            res.append(str + "\n");
        }
        return res.substring(0, res.length() - 1);
    }

    public static void cal(int smallNo, int smallV, int bigNo, int bigV, List<String> toFill) {
        toFill.add(smallNo + " " + smallV);
        int nums = bigNo - smallNo - 1;
        for (int i = 1; i <= nums; i++) {
            int curNo = smallNo + i;
            int curV = smallV + ((bigV - smallV) / (bigNo - smallNo)) * i;
            toFill.add(curNo + " " + curV);
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int M = in.nextInt();
            int N = in.nextInt();
            int[][] values = new int[M][2];
            for (int i = 0; i < M; i++) {
                values[i][0] = in.nextInt();
                values[i][1] = in.nextInt();
            }
            System.out.println(process(values));
        }
        in.close();
    }
}

牛客网-华为机试练习题 48

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

链表结点定义如下:

struct ListNode

{

int m_nKey;

ListNode* m_pNext;

};

详细描述:

本题为考察链表的插入和删除知识。

链表的值不能重复

构造过程,例如

1 <- 2

3 <- 2

5 <- 1

4 <- 5

7 <- 2

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

删除 结点 2

则结果为 7 3 1 5 4

输入描述:
1 输入链表结点个数
2 输入头结点的值
3 按照格式插入各个结点
4 输入要删除的结点的值
输出描述:
输出删除结点后的序列

示例1

输入

复制

5
2
3 2
4 3
5 2
1 4
3
输出

复制

2 1 5 4
解决代码:
import java.util.*;

/***********如果需要频繁地从列表的中间位置添加和移除元素,且只要顺序地访问列表元素时,LinkedList实现更好************/
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            handle(scanner);
        }
        scanner.close();
    }

    public static void handle(Scanner scanner) {
        String str = scanner.nextLine();
        LinkedList<Integer> linkedList = new LinkedList<Integer>();
        int loc = str.indexOf(" ");
        int num = Integer.parseInt(str.substring(0, loc));
        str = str.substring(loc + 1);
        loc = str.indexOf(" ");
        linkedList.add(Integer.parseInt(str.substring(0, loc)));
        str = str.substring(loc + 1);
        int start, end;
        end = -1;
        for (int i = 0; i < num - 1; i++) {
            start = end + 1;
            int loc1 = str.indexOf(" ", start);
            end = str.indexOf(" ", loc1 + 1);
            int node = Integer.parseInt(str.substring(start, loc1));
            int after = Integer.parseInt(str.substring(loc1 + 1, end));
            int location = linkedList.indexOf(after);
            linkedList.add(location + 1, node);
        }
        int deleteData = Integer.parseInt(str.substring(end + 1));
        linkedList.remove(new Integer(deleteData));
        for (Integer integer : linkedList) {
            System.out.print(integer + " ");
        }
        System.out.println();
    }
}
牛客网-华为机试练习题 49
题目描述

问题描述:有4个线程和1个公共的字符数组。线程1的功能就是向数组输出A,线程2的功能就是向字符输出B,线程3的功能就是向数组输出C,线程4的功能就是向数组输出D。要求按顺序向数组赋值ABCDABCDABCD,ABCD的个数由线程函数1的参数指定。[注:C语言选手可使用WINDOWS SDK库函数]
接口说明: void init(); //初始化函数 void Release(); //资源释放函数 unsignedint__stdcall ThreadFun1(PVOID pM) ;
//线程函数1,传入一个int类型的指针[取值范围:1 – 250,测试用例保证],用于初始化输出A次数,资源需要线程释放 unsignedint__stdcall ThreadFun2(PVOID pM) ;//线程函数2,无参数传入
unsignedint__stdcall ThreadFun3(PVOID pM) ;//线程函数3,无参数传入 Unsigned int __stdcall ThreadFunc4(PVOID pM);//线程函数4,无参数传入
char g_write[1032]; //线程1,2,3,4按顺序向该数组赋值。不用考虑数组是否越界,测试用例保证

输入描述:
输入一个int整数
输出描述:
输出多个ABCD

示例1
 输入

10
 输出

ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            StringBuilder sb = new StringBuilder();
            int N = Integer.parseInt(line);
            for (int i = 0; i < N; i++) {
                sb.append("ABCD");
            }
            System.out.println(sb);
        }
    }
}
牛客网-华为机试练习题 50
题目描述

请实现如下接口

​ /* 功能:四则运算

​ * 输入:strExpression:字符串格式的算术表达式,如: “3+2*{1+2*[-4/(8-6)+7]}”

​ * 返回:算术表达式的计算结果

​ */

public static int calculate(String strExpression)

​ {

​ /* 请实现*/

return 0;

​ }

约束:

  1. pucExpression字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。
  2. pucExpression算术表达式的有效性由调用者保证;
输入描述:
输入一个算术表达式
输出描述:
得到计算结果

示例1

 输入

3+2*{1+2*[-4/(8-6)+7]}

输出

25
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

//四则运算带括号
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            Stack<Character> stack = new Stack<>();
            List<Object> list = new ArrayList<>();
            for (int i = 0; i < line.length(); i++) {
                String T = "";
                boolean isN = false; // 负号
                if (i == 0 && line.charAt(i) == '-') {
                    isN = true;
                    ++i;
                } else if (line.charAt(i) == '-' && (line.charAt(i - 1) == '-' || line.charAt(i - 1) == '+'
                        || line.charAt(i - 1) == '*' || line.charAt(i - 1) == '/' || line.charAt(i - 1) == '('
                        || line.charAt(i - 1) == '[' || line.charAt(i - 1) == '{')) {
                    isN = true;
                    ++i;
                }
                while (i < line.length() && line.charAt(i) >= '0' && line.charAt(i) <= '9') {
                    T = T + line.charAt(i++);
                }
                if (!T.equals("")) {
                    --i;
                    if (isN) {
                        list.add(-(new Integer(T)));
                    } else {
                        list.add(new Integer(T));
                    }
                } else {
                    char op = line.charAt(i);
                    if (op == '+' || op == '-' || op == '*' || op == '/') {
                        if (stack.isEmpty()) {
                            stack.push(op);
                        } else if (isUpperPro(op, stack.peek())) {
                            stack.push(op);
                        } else {
                            while (!stack.isEmpty()
                                    && (stack.peek() != '(' || stack.peek() != '[' || stack.peek() != '{')
                                    && !isUpperPro(op, stack.peek())) {
                                list.add(stack.pop());
                            }
                            stack.push(line.charAt(i));
                        }
                    } else if (op == '(' || op == '[' || op == '{') {
                        stack.push(op);
                    } else if (line.charAt(i) == ')') {
                        while (stack.peek() != '(') {
                            list.add(stack.pop());
                        }
                        stack.pop();
                    } else if (line.charAt(i) == ']') {
                        while (stack.peek() != '[') {
                            list.add(stack.pop());
                        }
                        stack.pop();
                    } else if (line.charAt(i) == '}') {
                        while (stack.peek() != '{') {
                            list.add(stack.pop());
                        }
                        stack.pop();
                    }
                }
            }
            while (!stack.isEmpty()) {
                list.add(stack.pop());
            }
            Stack<Integer> Pstack = new Stack<Integer>();
            for (Object temp : list) {
                if (temp instanceof Integer) {
                    Pstack.push((Integer) temp);
                } else if (temp instanceof Character) {
                    int N2 = Pstack.pop();
                    int N1 = Pstack.pop();
                    int res = getRes(N1, N2, (char) temp);
                    Pstack.push(res);
                }
            }
            System.out.println(Pstack.pop());
        }
    }

    public static int getRes(int n1, int n2, char temp) {
        if (temp == '-') {
            return n1 - n2;
        }
        if (temp == '+') {
            return n1 + n2;
        }
        if (temp == '*') {
            return n1 * n2;
        }
        if (temp == '/') {
            return n1 / n2;
        }
        return 0;
    }

    public static boolean isUpperPro(char op, char peek) {
        if (peek == '(' || peek == '[' || peek == '{') {
            return true;
        }
        if ((op == '+' || op == '-') && (peek == '*' || peek == '/')) {
            return false;
        }
        if ((op == '*' || op == '/') && (peek == '+' || peek == '-')) {
            return true;
        }
        if ((op == '+' || op == '-') && (peek == '+' || peek == '-')) {
            return false;
        }
        if ((op == '*' || op == '/') && (peek == '*' || peek == '/')) {
            return false;
        }
        return false;
    }
}

牛客网-华为机试练习题 51
题目描述

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

链表结点定义如下:

struct ListNode

{

int       m_nKey;

ListNode* m_pNext;

};

详细描述:

接口说明

原型:

ListNode* FindKthToTail(ListNode* pListHead, unsignedint k);

输入参数:

ListNode* pListHead  单向链表

unsigned int k  倒数第k个结点

输出参数(指针指向的内存区域保证有效):

无

返回值:

正常返回倒数第k个结点指针,异常返回空指针
输入描述:
输入说明
1 输入链表结点个数
2 输入链表的值
3 输入k的值
输出描述:
输出一个整数

示例1

输入

8
1 2 3 4 5 6 7 8
4

输出

5
解决代码:
import java.util.Scanner;

/**
 * 输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第0个结点为链表的尾指针。
 */
class Node {
    int value;
    Node next = null;

    Node(int a) {
        this.value = a;
    }
}

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int num = Integer.valueOf(sc.nextLine());
            String[] values = sc.nextLine().split(" ");
            int k = Integer.valueOf(sc.nextLine());
            //初始化链表
            Node head = createList(values);
            //找到倒数第K个链表节点
            if (k == 0) {
                System.out.println(0);
            } else {
                Node result = lastKValueList(head, k);
                System.out.println(result.value);
            }
        }
    }

    public static Node createList(String[] values) {
        if (values.length <= 0) {
            return null;
        }
        Node head = new Node(Integer.valueOf(values[0]));//创建头节点
        Node temp = head;
        for (int i = 1; i < values.length; i++) {
            temp.next = new Node(Integer.valueOf(values[i]));
            temp = temp.next;
        }
        return head;
    }

    public static Node lastKValueList(Node head, int k) {
        Node fast = head;
        Node slow = head;

        for (int i = 0; i < k - 1; i++) {
            fast = fast.next;
        }

        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }

}

牛客网-华为机试练习题 52
题目描述

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

Ex:

字符串A:abcdefg

字符串B: abcdef

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

要求:

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

 

请实现如下接口

/*  功能:计算两个字符串的距离

 \*  输入: 字符串A和字符串B

 \*  输出:无

 \*  返回:如果成功计算出字符串的距离,否则返回-1

 */

​     **public**   **static**   **int**  calStringDistance (String charA, String  charB)

​    {

​        **return**  0;

​    }  
输入描述:
输入两个字符串
输出描述:
得到计算结果


示例1

输入

abcdefg
abcdef

输出

1
解决代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String sr = null;
        while ((sr = br.readLine()) != null) {
            char[] a = sr.toCharArray();
            String b = br.readLine();
            char[] c = b.toCharArray();
            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 <= c.length; i++) dp[0][i] = i;
            for (int i = 1; i < a.length + 1; i++) {
                for (int j = 1; j < c.length + 1; j++) {
                    if (a[i - 1] == c[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][j - 1] + 1, dp[i - 1][j - 1] + 1));
                }
            }
            System.out.println(dp[a.length][c.length]);
        }
    }

}
牛客网-华为机试练习题 53
题目描述

​            1

​         1  1  1

​      1  2  3  2  1

   1  3  6  7  6  3  1

1  4  10 16 19  16 10  4  1

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

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


输入n(n <= 1000000000)
输入描述:
输入一个int整数
输出描述:
输出返回的int值

示例1

输入

4
 
输出

3
解决代码:
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int num = in.nextInt();
            int[][] arrys = new int[num][];
            for (int i = 0; i < num; i++) {
                arrys[i] = new int[2 * i + 1];
            }
            getyanghuiTriangle(num, arrys);
            int i;
            for (i = 0; i < arrys[num - 1].length; i++) {
                if (arrys[num - 1][i] % 2 == 0) {
                    System.out.println(i + 1);
                    break;
                }
            }
            if (i == arrys[num - 1].length) {
                System.out.println("-1");
            }
        }
        in.close();
    }

    public static void getyanghuiTriangle(int num, int[][] arrys) {
        int num1;
        int num2;
        int num3;
        for (int i = 0; i < num; i++) {
            for (int j = 0; j < arrys[i].length; j++) {
                if (i == 0 || j == 0 || j == arrys[i].length - 1) {
                    arrys[i][j] = 1;
                } else {
                    if (j - 2 < 0) {
                        num1 = 0;
                    } else {
                        num1 = arrys[i - 1][j - 2];
                    }
                    num2 = arrys[i - 1][j - 1];
                    if (j >= arrys[i - 1].length) {
                        num3 = 0;
                    } else {
                        num3 = arrys[i - 1][j];
                    }
                    arrys[i][j] = num1 + num2 + num3;
                }
            }
        }
    }

}
牛客网-华为机试练习题 54
题目描述

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

输入字符串长度不超过100,合法的字符包括”+, -, *, /, (, )”,”0-9”,字符串内容的合法性及表达式语法的合法性由做题者检查。本题目只涉及整型计算。

输入描述:
输入算术表达式
输出描述:
计算出结果值

示例1

输入


400+5

输出

405
解决代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

public class Main {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            Stack<Character> stack = new Stack<Character>();
            List<Object> list = new ArrayList<Object>();

            //利用中缀表达式构建后缀表达式
            for (int i = 0; i < line.length(); ++i) {
                String T = "";
                while (i < line.length() && line.charAt(i) >= '0' && line.charAt(i) <= '9')
                    T = T + line.charAt(i++);
                if (!T.equals("")) {  //T不等于"",说明T是一个数字字符串
                    list.add(new Integer(T));  //转为一个Integer对象
                    --i;
                } else  // T等于空说明当前的charAt(i)不是数字 ,是操作符号
                {
                    if (line.charAt(i) == '(')//如果是( 则先入栈
                        stack.push(line.charAt(i));
                    else if (line.charAt(i) == '+' || line.charAt(i) == '-' || line.charAt(i) == '*' || line.charAt(i) == '/') /*是符号 并且优先级大于*/ {
                        if (stack.isEmpty())//若果栈是空的,直接加入第一个符号
                            stack.push(line.charAt(i));
                        else if (isUpperPro(line.charAt(i), stack.peek()))//新符号优先级大于栈顶
                            stack.push(line.charAt(i));
                        else {//新符号优先级低于栈顶
                            while (!stack.isEmpty() && stack.peek() != '(' && !isUpperPro(line.charAt(i), stack.peek()))
                                list.add(stack.pop());
                            stack.push(line.charAt(i));
                        }
                    } else if (line.charAt(i) == ')') {
                        while (stack.peek() != '(')
                            list.add(stack.pop());
                        stack.pop();
                    }
                }
            }
            while (!stack.isEmpty()) list.add(stack.pop());
            //利用后缀表达式求值
            Stack<Integer> pStack = new Stack<Integer>();
            for (Object temp : list) {
                if (temp instanceof Integer) pStack.push((Integer) temp);
                else if (temp instanceof Character) {
                    int temp2 = pStack.pop();   //要注意出栈进栈的顺序,使得操作数也不一样
                    int temp1 = pStack.pop();
                    int res = getOP(temp1, temp2, (char) temp);
                    pStack.push(res);
                }
            }
            System.out.println(pStack.pop());
        }
    }

    private static int getOP(int temp1, int temp2, char charAt) {
        if (charAt == '+') return temp1 + temp2;
        if (charAt == '-') return temp1 - temp2;
        if (charAt == '*') return temp1 * temp2;
        if (charAt == '/') return temp1 / temp2;
        return 0;
    }

    private static boolean isUpperPro(char charAt, char peek) {
        if (peek == '(')  //如果栈顶元素是(,那么新字符优先级大于栈顶的(
            return true;
        if ((charAt == '+' || charAt == '-') && (peek == '*' || peek == '/'))
            return false;
        if ((charAt == '*' || charAt == '/') && (peek == '-' || peek == '+'))
            return true;
        if ((charAt == '+' || charAt == '-') && (peek == '+' || peek == '-'))
            return false;
        if ((charAt == '*' || charAt == '/') && (peek == '*' || peek == '/'))
            return false;
        return false;
    }
}
牛客网-华为机试练习题 55
题目描述

输出7有关数字的个数,包括7的倍数,还有包含7的数字(如17,27,37…70,71,72,73…)的个数(一组测试用例里可能有多组数据,请注意处理)

输入描述:
一个正整数N。(N不大于30000)
输出描述:
不大于N的与7有关的数字个数,例如输入20,与7有关的数字包括7,14,17.


示例1

输入

20
输出


3
解决代码:
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int num = sc.nextInt();
            int count = 0;
            for (int i = 1; i <= num; i++) {
                if (aboutSeven(i)) {
                    count++;
                }
            }
            System.out.println(count);
        }
    }

    public static boolean aboutSeven(int num) {
        int temp = num;
        while (num != 0) {
            if (num % 10 == 7) {
                return true;
            } else {
                num = num / 10;
            }
        }
        while (temp > 0) {
            temp -= 7;
        }
        return temp == 0;
    }
}
牛客网-华为机试练习题 56
题目描述

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

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

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

给定函数count(int n),用于计算n以内(含n)完全数的个数。计算范围, 0 < n <= 500000

返回n以内完全数的个数。 异常情况返回-1


**/\****

*****

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

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

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

*****

 *****  **给定函数count(int n),用于计算n以内(含n)完全数的个数**

 *** @param n**  **计算范围, 0 < n <= 500000**

 *** @return n** **以内完全数的个数, 异常情况返回-1**

*****

 ***/**    

**public**   **static**   **int**  count( **int**  n)

输入描述:
输入一个数字
输出描述:
输出完全数的个数

示例1

输入

1000

输出

3
解决代码:
import java.util.*;

public class Main {
    private static boolean isPerfect(int src) {
        int sum = 1;
        for (int i = 2; i * i <= src; i++) {
            if (src % i == 0) {
                sum += i;
                sum += src / i;
            }
        }
        return sum == src;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int n = in.nextInt();
            int count = 0;
            //1不是完备数,从2开始遍历
            for (int i = 2; i <= n; i++) {
                if (isPerfect(i)) {
                    count++;
                }
            }
            System.out.println(count);
        }
    }
}
牛客网-华为机试练习题 57
题目描述

在计算机中,由于处理器位宽限制,只能处理有限精度的十进制整数加减法,比如在32位宽处理器计算机中,
参与运算的操作数和结果必须在-2^31~2^31-1之间。如果需要进行更大范围的十进制整数加法,需要使用特殊
的方式实现,比如使用字符串保存操作数和结果,采取逐位运算的方式。如下:
9876543210 + 1234567890 = ?
让字符串 num1="9876543210",字符串 num2="1234567890",结果保存在字符串 result = "11111111100"。
-9876543210 + (-1234567890) = ?
让字符串 num1="-9876543210",字符串 num2="-1234567890",结果保存在字符串 result = "-11111111100"。


要求编程实现上述高精度的十进制加法。
要求实现方法: 
public String add (String num1, String num2)
【输入】num1:字符串形式操作数1,如果操作数为负,则num1的前缀为符号位'-'
num2:字符串形式操作数2,如果操作数为负,则num2的前缀为符号位'-'
【返回】保存加法计算结果字符串,如果结果为负,则字符串的前缀为'-'
注:
(1)当输入为正数时,'+'不会出现在输入字符串中;当输入为负数时,'-'会出现在输入字符串中,且一定在输入字符串最左边位置;
(2)输入字符串所有位均代表有效数字,即不存在由'0'开始的输入字符串,比如"0012", "-0012"不会出现;
(3)要求输出字符串所有位均为有效数字,结果为正或0时'+'不出现在输出字符串,结果为负时输出字符串最左边位置为'-'。
输入描述:
输入两个字符串
输出描述:
输出给求和后的结果

示例1

输入

9876543210
1234567890

输出

11111111100
解决代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while ((str = bf.readLine()) != null) {
            BigInteger a = new BigInteger(str.trim());
            BigInteger b = new BigInteger(bf.readLine().trim());
            System.out.println(a.add(b).toString());
        }
        bf.close();
    }
}

牛客网-华为机试练习题 58
题目描述

输入n个整数,输出其中最小的k个。

详细描述:

接口说明

原型:

bool GetMinK(unsignedint uiInputNum, int * pInputArray, unsignedint uiK, int * pOutputArray);

输入参数:

​ unsignedint uiInputNum //输入整数个数

int * pInputArray //输入整数数组

unsignedint uiK //需输出uiK个整数

输出参数(指针指向的内存区域保证有效):

​ int * pOutputArray //最小的uiK个整数

返回值:

​ false 异常失败

​ true 输出成功

输入描述:
输入说明 
1 输入两个整数 
2 输入一个整数数组

输出描述:

输出一个整数数组

示例1

输入

5 2
1 3 5 7 2
输出

1 2
解决代码:
import java.util.Scanner;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String str1 = sc.nextLine();
            String str2 = sc.nextLine();
            String[] str1_arr = str1.split(" ");
            int num = Integer.parseInt(str1_arr[0]);
            int index = Integer.parseInt(str1_arr[1]);
            String[] str2_arr = str2.split(" ");
            String[] str2_sort = sort(str2_arr);
            for (int i = 0; i < index; i++) {
                if (i == index - 1)
                    System.out.println(str2_arr[i]);
                else
                    System.out.print(str2_arr[i] + " ");
            }
        }
    }

    public static String[] sort(String[] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (Integer.parseInt(arr[j + 1]) < Integer.parseInt(arr[j])) {
                    String temp = arr[j + 1];
                    arr[j + 1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        return arr;
    }
}

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


//输入n个整数,输出其中最小的k个。

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = "";
        while ((str = br.readLine()) != null) {
            int n = Integer.parseInt(str.split(" ")[0]);
            int k = Integer.parseInt(str.split(" ")[1]);
            String line = br.readLine();
            String[] chArr = line.split(" ");
            int[] intArr = new int[n];
            for (int i = 0; i < intArr.length; i++) {
                intArr[i] = Integer.parseInt(chArr[i]);
            }
            Arrays.sort(intArr);
            for (int i = 0; i < k; i++) {
                if (i == k - 1)
                    System.out.println(intArr[i]);
                else
                    System.out.print(intArr[i] + " ");
            }
        }
    }
}
牛客网-华为机试练习题 59
题目描述

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

输入描述:
输入一个非空字符串
输出描述:
输出第一个只出现一次的字符,如果不存在输出-1


示例1

输入

asdfasdfo

输出

o
解决代码:
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String str = sc.nextLine();
            char[] arr = str.toCharArray();
            int[] times = new int[128];
            for (int i = 0; i < str.length(); i++) {
                times[str.charAt(i)]++;
            }
            for (int i = 0; i < str.length(); i++) {
                if (times[arr[i]] == 1) {
                    System.out.println(arr[i]);
                    break;
                }
                if (i == str.length() - 1) {
                    System.out.println(-1);
                }
            }
        }
    }
}

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

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = "";
        while ((str = br.readLine()) != null) {
            String s = "";
            char[] c = str.toCharArray();
            int[] num = new int[128];
            for (int i = 0; i < str.length(); i++) {
                num[str.charAt(i)]++;
            }
            for (int i = 0; i < str.length(); i++) {
                if (num[c[i]] == 1) {
                    System.out.println(c[i]);
                    break;
                }
                if (i == str.length() - 1) System.out.println(-1);
            }

        }
    }
}
牛客网-华为机试练习题 60
题目描述

任意一个偶数(大于2)都可以由2个素数组成,组成偶数的2个素数有很多种情况,本题目要求输出组成指定偶数的两个素数差值最小的素数对

输入描述:
输入一个偶数
输出描述:
输出两个素数


示例1

输入

20


输出

7
13
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while ((str = bf.readLine()) != null) {
            int n = Integer.valueOf(str);
            int min = n;
            int a = 0;
            int b = 0;
            for (int i = 2; i <= n / 2; i++) {
                if (sushu(i) || sushu(n - i)) continue;
                int temp = Math.abs((n - i - i));
                if (temp < min) {
                    min = temp;
                    a = i;
                    b = n - i;
                }
            }
            System.out.println(a + "\n" + b);
        }
        bf.close();
    }

    public static boolean sushu(int n) {
        for (int i = 2; i * i <= n; i++) {
            if (n % i == 0) return true;
        }
        return false;
    }
}

牛客网-华为机试练习题 61
题目描述

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

输入

每个用例包含二个整数M和N。0<=m<=10,1<=n<=10。

样例输入

7 3

样例输出

8

/**

* 计算放苹果方法数目

* 输入值非法时返回-1

* 1 <= m,n <= 10

* @param m 苹果数目

* @param n 盘子数目数

* @return 放置方法总数

*/

public static int count(int m, int n)

输入描述:
输入两个int整数
输出描述:
输出结果,int型


示例1

输入

7 3

 输出

8
解决代码:
import java.util.*;

/**
 * 放苹果分为两种情况,一种是有盘子为空,一种是每个盘子上都有苹果。
 令(m,n)表示将m个苹果放入n个盘子中的摆放方法总数。
 1.假设有一个盘子为空,则(m,n)问题转化为将m个苹果放在n-1个盘子上,即求得(m,n-1)即可
 2.假设所有盘子都装有苹果,则每个盘子上至少有一个苹果,即最多剩下m-n个苹果,问题转化为将m-n个苹果放到n个盘子上
 即求(m-n,n)
 */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int m = sc.nextInt();
            int n = sc.nextInt();
            if (m < 1 || n > 10) {
                System.out.println(-1);
            } else {
                System.out.println(shareCount(m, n));
            }

        }
    }

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

牛客网-华为机试练习题 62
题目描述

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

输入

每个用例包含二个整数M和N。0<=m<=10,1<=n<=10。

样例输入

7 3

样例输出

8

/**

\* 计算放苹果方法数目


\* 输入值非法时返回-1

\* 1 <= m,n <= 10

\* @param m 苹果数目

\* @param n 盘子数目数

\* @return 放置方法总数

*

*/

public static int count(int m, int n)

输入描述:
输入两个int整数
输出描述:
输出结果,int型

示例1

输入

7 3
 
输出

8
解决代码
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String[] arr = sc.nextLine().split(" ");
            int m = Integer.parseInt(arr[0]);
            int n = Integer.parseInt(arr[1]);
            int res = F(m, n);
            System.out.println(res);
        }
    }

    public static int F(int x, int y) {
        if (x == 0 || y == 1) {
            return 1;
        } else if (x < y) {
            return F(x, x);
        } else {
            return F(x, y - 1) + F(x - y, y);
        }
    }
}

牛客网-华为机试练习题 63
题目描述

请实现如下接口

public static int findNumberOf1( int num)

​ {

​ /* 请实现 */

return 0;

​ } 譬如:输入5 ,5的二进制为101,输出2

涉及知识点:

输入描述:
输入一个整数
输出描述:
计算整数二进制中1的个数


示例1

 输入

5
输出


2
解决代码:
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            int num = Integer.parseInt(sc.nextLine());
            int count = 0;
            while (num > 0) {
                num = num & num - 1;
                count++;
            }
            System.out.println(count);
        }
    }
}
牛客网-华为机试练习题 64
题目描述

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

给定一个很长的DNA序列,以及要求的最小子序列长度,研究人员经常会需要在其中找出GC-Ratio最高的子序列。

输入描述:
输入一个string型基因序列,和int型子串的长度
输出描述:
找出GC比例最高的子串,如果有多个输出第一个的子串

示例1

输入

AACTGTGCACGACCTGA
5

输出

GCACG
解决代码:
import java.io.*;

public class Main {
    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while ((str = br.readLine()) != null) {
            int maxRadio = 0;
            int index = 0;
            int n = Integer.parseInt(br.readLine());
            for (int i = 0; i <= str.length() - n; i++) {
                int temp = getMaxRadio(str.substring(i, i + n));
                if (temp > maxRadio) {
                    maxRadio = temp;
                    index = i;
                }
            }
            System.out.println(str.substring(index, index + n));
        }
    }

    public static int getMaxRadio(String str) {
        int count = 0;
        for (int i = 0; i < str.length(); i++) {
            if ('G' == str.charAt(i) || 'C' == str.charAt(i)) {
                count++;
            }
        }
        return count;
    }

}


牛客网-华为机试练习题 65
题目描述

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

现在要实现通过上下键控制光标移动来浏览歌曲列表,控制逻辑如下:

  1. 歌曲总数<=4的时候,不需要翻页,只是挪动光标位置。

光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲;光标在最后一首歌曲时,按Down键光标挪到第一首歌曲。

img

其他情况下用户按Up键,光标挪到上一首歌曲;用户按Down键,光标挪到下一首歌曲。

img

\2. 歌曲总数大于4的时候(以一共有10首歌为例):

特殊翻页:屏幕显示的是第一页(即显示第1 –
4首)时,光标在第一首歌曲上,用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),同时光标放到最后一首歌上。同样的,屏幕显示最后一页时,光标在最后一首歌曲上,用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。

img

一般翻页:屏幕显示的不是第一页时,光标在当前屏幕显示的第一首歌曲时,用户按Up键后,屏幕从当前歌曲的上一首开始显示,光标也挪到上一首歌曲。光标当前屏幕的最后一首歌时的Down键处理也类似。

img

其他情况,不用翻页,只是挪动光标就行。

输入描述:
输入说明:
1 输入歌曲数量
2 输入命令 U或者D
输出描述:
输出说明
1 输出当前列表
2 输出当前选中歌曲

示例1

输入

10
UUUU

输出

7 8 9 10
7
解决代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static String[] music(String str, int n) {
        int point = 1;//光标
        int head = 1;//屏幕的第一首歌
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (n <= 4) {
                if (c == 'U') {
                    if (point == head) point = n;
                    else point -= 1;
                }
                if (c == 'D') {
                    if (point == head + n - 1) point = 1;
                    else point += 1;
                }
                continue;
            }
            if (c == 'U') {//向上
                if (point == head) {//需要向上翻页
                    if (point == 1) {//特殊翻页
                        point = n;
                        head = n - 3;
                    } else {//普通翻页
                        point = point - 1;
                        head = head - 1;
                    }
                } else {//不需要翻页
                    point -= 1;
                }
            }
            if (c == 'D') {//向下
                if (point == head + 3) {//需要向下翻页
                    if (point == n) {//特殊翻页
                        point = 1;
                        head = 1;
                    } else {//普通翻页
                        point += 1;
                        head += 1;
                    }
                } else {//无需翻页
                    point += 1;
                }
            }
        }
        String[] strary = new String[2];
        strary[0] = head + " " + (head + 1) + " " + (head + 2) + " " + (head + 3);
        if (n <= 4) {
            strary[0] = head + "";
            for (int i = 0; i < n - 1; i++) {
                strary[0] = strary[0] + " " + (head + i + 1);
            }
        }
        strary[1] = point + "";
        return strary;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            int n = Integer.valueOf(line);
            String str = br.readLine();
            System.out.println(music(str, n)[0]);
            System.out.println(music(str, n)[1]);
        }
    }
}

牛客网-华为机试练习题 66
题目描述

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

输入描述:
输入两个字符串
输出描述:
返回重复出现的字符


示例1

输入

abcdefghijklmnop
abcsafjklmnopqrstuvw


输出

jklmnop

解决代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static String lcs(String str1, String str2) {
        String strshort = "";
        String strlong = "";
        if (str1.length() <= str2.length()) {
            strshort = str1;
            strlong = str2;
        } else {
            strshort = str2;
            strlong = str1;
        }
        int s1len = strshort.length();
        int s2len = strlong.length();
        int[][] dp = new int[s1len + 1][s2len + 1];
        for (int i = 0; i < s1len + 1; i++) {
            for (int j = 0; j < s2len + 1; j++) {
                if (i == 0 || j == 0) dp[i][j] = 0;
                else {
                    if (strlong.charAt(j - 1) == strshort.charAt(i - 1)) dp[i][j] = dp[i - 1][j - 1] + 1;
                    else dp[i][j] = 0;
                }
            }
        }
        int max = (int) (-Math.pow(2, 31));
        int maxi = 0;
        int maxj = 0;
        for (int i = 0; i < s1len + 1; i++) {
            for (int j = 0; j < s2len + 1; j++) {
                if (dp[i][j] > max) {
                    max = dp[i][j];
                    maxi = i - dp[i][j] + 1;
                    maxj = i;
                }
            }
        }
        return strshort.substring(maxi - 1, maxj);
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            String str = br.readLine();
            System.out.println(lcs(line, str));
        }
    }
}
牛客网-华为机试练习题 67
题目描述

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

命 令执 行
resetreset what
reset boardboard fault
board addwhere to add
board deletno board at all
reboot backplaneimpossible
backplane abortinstall first
he heunkown command

注意:he he不是命令。

为了简化输入,方便用户,以“最短唯一匹配原则”匹配: 1、若只输入一字串,则只匹配一个关键字的命令行。例如输入:r,根据该规则,匹配命令reset,执行结果为:reset
what;输入:res,根据该规则,匹配命令reset,执行结果为:reset what; 2、若只输入一字串,但本条命令有两个关键字,则匹配失败。例如输入:reb,可以找到命令reboot
backpalne,但是该命令有两个关键词,所有匹配失败,执行结果为:unkown command 3、若输入两字串,则先匹配第一关键字,如果有匹配但不唯一,继续匹配第二关键字,如果仍不唯一,匹配失败。例如输入:r
b,找到匹配命令reset board,执行结果为:board fault。

4、若输入两字串,则先匹配第一关键字,如果有匹配但不唯一,继续匹配第二关键字,如果唯一,匹配成功。例如输入:b a,无法确定是命令board add还是backplane abort,匹配失败。
5、若输入两字串,第一关键字匹配成功,则匹配第二关键字,若无匹配,失败。例如输入:bo a,确定是命令board add,匹配成功。 6、若匹配失败,打印“unkown command”

输入描述:
多行字符串,每行字符串一条命令
输出描述:
执行结果,每条命令输出一行

示例1

输入
reset
reset board
board add
board delet
reboot backplane
backplane abort
输出
reset what
board fault
where to add
no board at all
impossible
install first
解决代码:
import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        HashMap<String, String> hMap = new HashMap<>();
        //HashMap<String, String> hMap = new HashMap<>();
        hMap.put("reset", "reset what");
        hMap.put("reset board", "board fault");
        hMap.put("board add", "where to add");
        hMap.put("board delet", "no board at all");
        hMap.put("reboot backplane", "impossible");
        hMap.put("backplane abort", "install first");
        String str = br.readLine();
        while (str != null) {
            System.out.println(hMap.getOrDefault(str, "unkown command"));
            str = br.readLine();
        }
    }
}

牛客网-华为机试练习题 68
题目描述

问题描述:给出4个1-10的数字,通过加减乘除,得到数字为24就算胜利 输入: 4个1-10的数字。[数字允许重复,但每个数字仅允许使用一次,测试用例保证无异常数字]
输出: true or false

输入描述:
输入4个int整数
输出描述:
返回能否得到24点,能输出true,不能输出false

示例1

输入

7 2 1 10

输出

true
解决代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            String[] strs = line.split(" ");
            List<Integer> list = new ArrayList<>();
            for (int i = 0; i < 4; i++) {
                list.add(Integer.parseInt(strs[i]));
            }
            boolean flag = fun(list);
            System.out.println(flag);
        }
    }

    public static boolean fun(List<Integer> list) {
        for (int i = 0; i < list.size(); i++) {
            int temp = list.get(i);
            list.remove(i);
            if (getResult(list, temp)) {
                return true;
            }
            list.add(i, temp);
        }
        return false;
    }

    public static boolean getResult(List<Integer> list, int temp) {
        if (list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                int n = list.get(i);
                list.remove(i);
                if (getResult(list, temp * n) || getResult(list, temp + n) || getResult(list, temp - n)) {
                    return true;
                } else if (temp % n == 0) {
                    if (getResult(list, temp / n)) {
                        return true;
                    }
                }
                list.add(i, n);
            }
            return false;
        } else {
            return temp == 24;
        }
    }
}

牛客网-华为机试练习题 69
题目描述

查找和排序

题目:输入任意(用户,成绩)序列,可以获得成绩从高到低或从低到高的排列,相同成绩 都按先录入排列在前的规则处理。

例示: jack 70 peter 96 Tom 70 smith 67

从高到低 成绩
peter 96
jack 70
Tom 70
smith 67

从低到高

smith 67

Tom 70
jack 70
peter 96

输入描述:
输入多行,先输入要排序的人的个数,然后分别输入他们的名字和成绩,以一个空格隔开
输出描述:
按照指定方式输出名字和成绩,名字和成绩之间以一个空格隔开

输入

3
0
fang 90
yang 50
ning 70


 输出

fang 90
ning 70
yang 50
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while ((str = reader.readLine()) != null) {
            //获取要排序的人的个数
            int count = Integer.parseInt(str);
            //获取输入的排序方法(升序还是降序)
            int sortType = Integer.parseInt(reader.readLine());
            String[] users = new String[count];
            int[] scores = new int[count];
            for (int i = 0; i < count; i++) {
                String line = reader.readLine();
                String[] parts = line.split(" ");
                String user = parts[0];
                int score = Integer.parseInt(parts[1]);
                if (sortType == 0) {
                    int j = 0;
                    for (j = i - 1; j >= 0; j--) {
                        if (scores[j] < score) {
                            scores[j + 1] = scores[j];
                            users[j + 1] = users[j];
                        } else {
                            break;
                        }
                    }
                    scores[j + 1] = score;
                    users[j + 1] = user;
                } else {
                    int j = 0;
                    for (j = i - 1; j >= 0; j--) {
                        if (scores[j] > score) {
                            scores[j + 1] = scores[j];
                            users[j + 1] = users[j];
                        } else {
                            break;
                        }
                    }
                    scores[j + 1] = score;
                    users[j + 1] = user;
                }
            }
            for (int i = 0; i < count; i++) {
                System.out.println(users[i] + " " + scores[i]);
            }
        }
    }
}

牛客网-华为机试练习题 70
题目描述
  • 如果A是个x行y列的矩阵,B是个y行z列的矩阵,把A和B相乘,其结果将是另一个x行z列的矩阵C。这个矩阵的每个元素是由下面的公式决定的:

原型:

voidmatrix_multiply(int *m1,int *m2,int *r, int x, int y, int z);

输入参数:

​ int *m1:x行y列的矩阵(array1[x][y])

​ int *m2:y行z列的矩阵(array2[y][z])

​ int x:矩阵m1的行数

​ int y:矩阵m1的列数/矩阵m2的行数

​ int z:矩阵m2的列数

输出参数:

​ int *r:矩阵m1, m2相乘的结果(array3[x][z])

返回值:

​ void

输入描述:
输入说明:
1、第一个矩阵的行数
2、第一个矩阵的列数和第二个矩阵的行数
3、第二个矩阵的列数
4、第一个矩阵的值
5、第二个矩阵的值
输出描述:
输出两个矩阵相乘的结果


示例1

输入

2
2
2
3 8
8 0
9 0
18 9

 输出


171 72
72 0
解决代码:
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int r1, c1, r2, c2;
            r1 = Integer.parseInt(sc.nextLine());
            c1 = Integer.parseInt(sc.nextLine());
            r2 = c1;
            c2 = Integer.parseInt(sc.nextLine());
            int[][] x = new int[r1][c1];
            int[][] y = new int[r2][c2];
            for (int i = 0; i < r1; i++) {
                String[] str = sc.nextLine().split(" ");
                for (int j = 0; j < str.length; j++) {
                    x[i][j] = Integer.parseInt(str[j]);
                }
            }
            for (int i = 0; i < r2; i++) {
                String[] str = sc.nextLine().split(" ");
                for (int j = 0; j < str.length; j++) {
                    y[i][j] = Integer.parseInt(str[j]);
                }
            }
            print2DArray(matrixMultiplication(x, y));
        }
        sc.close();
    }

    private static int[][] matrixMultiplication(int[][] x, int[][] y) {
        int r1 = x.length, c1 = x[0].length, r2 = y.length, c2 = y[0].length;
        int[][] result = new int[r1][c2];
        for (int i = 0; i < r1; i++) {
            for (int j = 0; j < c2; j++) {
                result[i][j] = getResult(x, i, y, j);
            }
        }
        return result;
    }

    private static int getResult(int[][] x, int r, int[][] y, int c) {
        int r1 = x.length, c1 = x[0].length, r2 = y.length, c2 = y[0].length;
        int[] a = new int[c1];
        int[] b = new int[r2];
        for (int i = 0; i < c1; i++) {
            a[i] = x[r][i];
            b[i] = y[i][c];
        }
        int sum = 0;
        for (int i = 0; i < c1; i++) {
            sum = sum + a[i] * b[i];
        }
        return sum;
    }

    public static void print2DArray(int[][] a) {
        StringBuffer sb = new StringBuffer();
        for (int[] ints : a) {
            for (int j = 0; j < ints.length - 1; j++) {
                sb.append(ints[j]).append(" ");
            }
            sb.append(ints[ints.length - 1]).append("\n");
        }
        System.out.println(sb.toString().substring(0, sb.length() - 1));
    }

}
牛客网-华为机试练习题 71
题目描述

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

例如:

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

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

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

输入描述:
输入多行,先输入要计算乘法的矩阵个数n,每个矩阵的行数,列数,总共2n的数,最后输入要计算的法则
输出描述:
输出需要进行的乘法次数


示例1
输入

3
50 10
10 20
20 5
(A(BC))


输出

3500
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static int getNo(String str, int[][] data) {
        int total = 0;
        //读右括号
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c == ')') {
                for (int j = i - 1; j >= 0; j--) {
                    char c1 = str.charAt(j);
                    if (c1 == '(') {
                        while (str.charAt(j + 2) != ')') {
                            char c2 = str.charAt(j + 1);
                            char c3 = str.charAt(j + 2);
                            total += data[c2 - 65][0] * data[c2 - 65][1] * data[c3 - 65][1];
                            //需要改变数组,改变字符串
                            data[c2 - 65][1] = data[c3 - 65][1];
                            str = str.substring(0, j + 2) + str.substring(j + 3);
                        }
                        //i位置的)与j为止的(要删除
                        //str已经变短,j+1不见了,i--
                        i--;
                        str = (j == 0 ? "" : str.substring(0, j)) + str.substring(j + 1, i) + (i == str.length() - 1 ? "" : str.substring(i + 1));
                        //i指向原来左括号的位置
                        i = j;
                        break;
                    }
                }
            }
        }
        return total;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            int n = Integer.valueOf(line);
            int[][] data = new int[n][2];
            for (int i = 0; i < n; i++) {
                line = br.readLine();
                int x = Integer.parseInt(line.substring(0, line.lastIndexOf(" ")));
                int y = Integer.parseInt(line.substring(line.lastIndexOf(" ") + 1));
                data[i][0] = x;
                data[i][1] = y;
            }
            line = br.readLine();
            System.out.println(getNo(line, data));
        }
    }
}

牛客网-华为机试练习题 72
题目描述

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

输入: 通配符表达式; 一组字符串。

输出: 返回匹配的结果,正确输出true,错误输出false

输入描述:
先输入一个带有通配符的字符串,再输入一个需要匹配的字符串
输出描述:
返回匹配的结果,正确输出true,错误输出false

示例1

输入

te?t*.*
txt12.xls

输出


false
解决代码:
/*问题描述:在计算机中,通配符一种特殊语法,广泛应用于文件搜索、数据库、正则表达式等领域。现要求各位实现字符串通配符的算法。
要求:
实现如下2个通配符:
*:匹配0个或以上的字符(字符由英文字母和数字0-9组成,不区分大小写。下同)
?:匹配1个字符
输入:
通配符表达式;
一组字符串。
输出:
返回匹配的结果,正确输出true,错误输出false
 
te?t*.*
txt12.xls
 
false
*/

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

public class Main {
    public static boolean isMatch(String str1, String str2) {
        str1 = str1.replaceAll("\\?", "[0-9a-zA-Z]");//把str1变成正则表达式
        str1 = str1.replaceAll("\\*", "[0-9a-zA-Z]*");
        str1 = str1.replaceAll("\\.", "\\.");
        return str2.matches(str1);
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            String str = br.readLine();
            System.out.println(isMatch(line, str));
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值