华为od机试题2 真题

以下题目附带Java解法,是我个人写的,不一定是标准答案,没有真正的测试数据,只能说是我自己认为通过率100%,也不一定是最优解。如果有错误或是有更好的解法,请评论告诉我!!!

77.满足最大消费额度

  双十一众多商品进行打折销售
  小明想购买自己心仪的一些物品
  但由于购买资金限制
  所以他决定从众多心仪商品中购买三件
  而且想尽可能得花完资金
  现在请你设计一个程序 计算小明尽可能花费的最大资金数

输入描述:
输入第一行为一维整型数组m
数组长度小于100
数组元素记录单个商品的价格
单个商品加个小于1000

输入第二行为购买资金的额度r
r<100000

输出描述:
 输出为满足上述条件的最大花费额度

   注意:如果不存在满足上述条件的商品请返回-1

  示例:
 输入
  23,26,36,27
  78
 输出
  76
 说明:
  金额23、26、27得到76而且最接近且小于输入金额78

   示例:
 输入
 23,30,40
 26
 输出
 -1
 说明
   因为输入的商品无法满足3件之和小于26
   故返回-1

   输入格式正确无需考虑输入错误情况4
// 满足最大消费额度
    public static void test077() {
        Scanner sc = new Scanner(System.in);
        String line1 = sc.nextLine();
        String line2 = sc.nextLine();
        String[] split = line1.split(",");
        int len = split.length;
        int sum = 0;
        // 依次遍历,列出所有的三数之和
        for (int i = 0; i < len - 2; i++) {
            for (int j = i + 1; j < len - 1; j++) {
                for (int k = j + 1; k < len; k++) {
                    int res = Integer.parseInt(split[i]) + Integer.parseInt(split[j]) + Integer.parseInt(split[k]);
                    if (res < Integer.parseInt(line2)) {
                        // 与原来的值比较,留下大的值
                        sum = Math.max(sum, res);
                    }
                }
            }
        }
        if (sum == 0) {
            System.out.println(-1);
        } else {
            System.out.println(sum);
        }
    }

76.小朋友身高位置

  在学校中
  N个小朋友站成一队
  第i个小朋友的身高为height[i]
  第i个小朋友可以看到第一个比自己身高更高的小朋友j
  那么j是i的好朋友
  (要求:j>i)
  请重新生成一个列表
  对应位置的输出是每个小朋友的好朋友的位置
  如果没有看到好朋友
  请在该位置用0代替
  小朋友人数范围 0~40000

  输入描述:
第一行输入N
N表示有N个小朋友

第二行输入N个小朋友的身高height[i]
都是整数

  输出描述:
输出N个小朋友的好朋友的位置

  示例1:
 输入:
   2
   100 95
  输出
   0 0
 说明
   第一个小朋友身高100站在队伍末尾
   向队首看 没有比他身高高的小朋友
   所以输出第一个值为0
   第二个小朋友站在队首前面也没有比他身高高的小朋友
   所以输出第二个值为0

   示例2:
  输入
    8
    123 124 125 121 119 122 126 123
  输出
    1 2 6 5 5 6 0 0
   说明:
   123的好朋友是1位置上的124
   124的好朋友是2位置上的125
   125的好朋友是6位置上的126
    依此类推
// 小朋友身高位置
    public static void test076() {
        Scanner sc = new Scanner(System.in);
        // 数组长度
        int len = Integer.parseInt(sc.nextLine());
        String line = sc.nextLine();
        String[] split = line.split(" ");
        // 双层循环,依次往后比较
        for (int i = 0; i < len - 1; i++) {
            for (int j = i + 1; j < len; j++) {
                if (Integer.parseInt(split[i]) < Integer.parseInt(split[j])) {
                    System.out.print(j + " ");
                    break;
                }
                // 当看到最后一个,还没结束,说明没有,输出0
                if (j == len - 1) {
                    System.out.print(0 + " ");
                }
            }
        }
        // 队首直接输出0
        System.out.print(0);
    }

75.字符连续出现最大次数

  输入一串字符串
  字符串长度不超过100
  查找字符串中相同字符连续出现的最大次数

  输入描述
    输入只有一行,包含一个长度不超过100的字符串

  输出描述
    输出只有一行,输出相同字符串连续出现的最大次数

   说明:
 输出

   示例1:
 输入
   hello
 输出
   2

示例2:
  输入
   word
  输出
   1

 示例3:
  输入
    aaabbc
   输出
    3

字符串区分大小写
    // 字符连续出现最大次数
    public static void test075() {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        String[] split = line.split("");
        // 出现次数,初始值为1
        int sum = 1;
        // 最大次数
        int res = 0;
        for (int i = 0; i < split.length; i++) {
            // 连续相同字符串
            while (i + 1 < split.length && split[i].equals(split[i + 1])) {
                sum++;
                i++;
            }
            // 比较出最大的
            res = Math.max(res, sum);
            // 初始化出现次数
            sum = 1;
        }
        System.out.println(res);
    }

74.最少停车数

特定大小的停车场 数组cars表示
其中1表示有车  0表示没车
车辆大小不一,小车占一个车位(长度1)
货车占两个车位(长度2)
卡车占三个车位(长度3)
统计停车场最少可以停多少辆车
返回具体的数目

输入描述:
  整型字符串数组cars
  其中1表示有车0表示没车
  数组长度<1000

输出描述:
  整型数字字符串
  表示最少停车数

示例1:
  输入
    1,0,1
  输出
    2
  说明:
    一个小车占第一个车位
    第二个车位空,一个小车占第三个车位
    最少有两辆车

 示例2:
   输入:
     1,1,0,0,1,1,1,0,1
   输出:
     3
   说明:
     一个货车占第1,2个车位
     第3,4个车位空
     一个卡车占第5,6,7个车位
     第8个车位空
     一个小车占第9个车位
     最少3俩个车
// 最少停车数
    public static void test074() {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        String[] split = line.split(",");
        // 连续1的次数
        int count = 0;
        // 找出所有的连续1的次数,存在list中
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < split.length; i++) {
            // 找出连续1的次数
            while (i < split.length && "1".equals(split[i])) {
                count++;
                i++;
            }
            // 连续1的次数大于0,存入list中
            if (count != 0) {
                list.add(count);
            }
            // 初始化
            count = 0;
        }
        int res = 0;
        for (int i = 0; i < list.size(); i++) {
            // 累加结果,算出能停几辆卡车
            res += list.get(i) / 3;
            // 如果%3有剩余的,则再加一辆,不用管余1还是余2,最小都是一辆
            if (list.get(i) % 3 != 0) {
                res++;
            }
        }
        System.out.println(res);
    }

73.字母多条件排序

给出一个只包含字母的字符串,
不包含空格,统计字符串中各个子字母(区分大小写)出现的次数,
并按照字母出现次数从大到小的顺序输出各个字母及其出现次数
如果次数相同,按照自然顺序排序,且小写字母在大写字母之前

输入描述:
  输入一行仅包含字母的字符串

输出描述:
  按照字母出现次数从大到小的顺序输出各个字母和字母次数,
  用英文分号分割,
  注意末尾的分号
  字母和次数中间用英文冒号分隔

示例:
    输入: xyxyXX
    输出:x:2;y:2;X:2;
说明:每个字符出现的次数为2 故x排在y之前
而小写字母x在大写X之前

示例2:
    输入:
     abababb
    输出:
        b:4;a:3
    说明:b的出现个数比a多 故排在a前
// PS:这道题按我的理解我做的是对的,先按次数排序,排完在按a~z A~Z排序。但是案例给的不清楚,或许可以 a~z中按次数排序,后在A~Z中按次数排序,就是小写在前,大写在后
    // 字母多条件排序
    public static void test073() {
        Scanner sc = new Scanner(System.in);
        char[] chars = sc.nextLine().toCharArray();
        // 用一个map,key存字符,value存字符出现次数
        Map<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            if (map.containsKey(c)) {
                map.put(c, map.get(c) + 1);
            } else {
                map.put(c, 1);
            }
        }
        // 小写字符的ACSII码大于大写字符, a~z 递增  A~Z递增  
        Set<Map.Entry<Character, Integer>> entries = map.entrySet();
        // 排序  排序规则:当返回的数字大于0,则进行换位置,否则不换
        entries.stream().sorted((s1, s2) -> {
            // 按次数排序
            if (s1.getValue() - s2.getValue() != 0) {
                return s2.getValue() - s1.getValue();
            }
            Character key1 = s1.getKey();
            Character key2 = s2.getKey();
            // a~z 两个小写字母之间的比较
            if (key1.compareTo('A') > 25 && key2.compareTo('A') > 25) {
                return key1 - key2;  // 字符a~z  A~Z之间加减返回数字
            }
            // A~Z 两个大写字母之间的比较
            if (key1.compareTo('A') < 26 && key2.compareTo('A') < 26) {
                return key1 - key2;
            }
            // a~z 混 A~Z  大小写字母之间的比较,大写在后
            return -(key1 - key2);
        }).forEach((s) -> {
            System.out.print(s.getKey() + ":" + s.getValue() + ";");
        });
    }

71. 交叉排序

现在有一队小朋友,他们高矮不同,
我们以正整数数组表示这一队小朋友的身高,如数组{5,3,1,2,3}。
我们现在希望小朋友排队,以“高”“矮”“高”“矮”顺序排列,
每一个“高”位置的小朋友要比相邻的位置高或者相等;
每一个“矮”位置的小朋友要比相邻的位置矮或者相等;
要求小朋友们移动的距离和最小,第一个从“高”位开始排,输出最小移动距离即可。
例如,在示范小队{5,3,1,2,3}中,{5, 1, 3, 2, 3}是排序结果。
{5, 2, 3, 1, 3} 虽然也满足“高”“矮”“高”“矮”顺序排列,
但小朋友们的移动距离大,所以不是最优结果。
移动距离的定义如下所示:
第二位小朋友移到第三位小朋友后面,移动距离为1,
若移动到第四位小朋友后面,移动距离为2;

输入描述:
    排序前的小朋友,以英文空格的正整数:
    4 3 5 7 8
    注:小朋友<100个
输出描述:
    排序后的小朋友,以英文空格分割的正整数:
    4 3 7 5 8
备注:4(高)3(矮)7(高)5(矮)8(高),
输出结果为最小移动距离,只有5和7交换了位置,移动距离都是1.

 示例一:
 输入
   4 1 3 5 2
 输出
   4 1 5 2 3

 示例二:
 输入
   1 1 1 1 1
 输出
   1 1 1 1 1
 说明:相邻位置可以相等

 示例三:
 输入:
   xxx
 输出
   []
 说明:出现非法参数情况,返回空数组
// PS:对案例
    //      输入
    //       4 1 3 5 2
    //     输出
    //       4 1 5 2 3
    // 有疑问,最有不应该是 4 1 3 2 5 吗??? 代码是照着案例写的,我认为通过率没有100%,没有测试数据,网上好多答案也是这样子写的,懵了
    // 交叉排序
    public static void test071() {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        List<Integer> list = new ArrayList<>();
        try {
            String[] split = line.split(" ");
            for (int i = 0; i < split.length; i++) {
                list.add(Integer.parseInt(split[i]));
            }
        }catch (Exception e){
            // 输入异常情况
            System.out.println("[]");
            return;
        }
        // 用于判断当前是高矮 还是 矮高
        boolean flag = true;
        for (int i = 0; i + 1 < list.size(); i++) {
            if (flag) {
                // 高 矮
                if (list.get(i) < list.get(i + 1)) {
                    // 是矮 高,则交换位置
                    int temp = list.get(i);
                    list.set(i, list.get(i + 1));
                    list.set(i + 1, temp);
                }
                // 判断完高 矮,切换为 矮 高
                flag = false;
            } else {
                // 矮 高
                if (list.get(i) > list.get(i + 1)) {
                    // 是高 矮,则交换位置
                    int temp = list.get(i);
                    list.set(i, list.get(i + 1));
                    list.set(i + 1, temp);
                }
                // 判断完矮 高,切换为高 矮
                flag = true;
            }
        }
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i) + " ");
        }
    }

70.水仙花数

所谓的水仙花数是指一个n位的正整数其各位数字的n次方的和等于该数本身,
例如153=1^3+5^3+3^3,153是一个三位数
输入描述
    第一行输入一个整数N,
    表示N位的正整数N在3-7之间包含3,7
    第二行输入一个正整数M,
    表示需要返回第M个水仙花数
输出描述
    返回长度是N的第M个水仙花数,
    个数从0开始编号,
    若M大于水仙花数的个数返回最后一个水仙花数和M的乘积,
    若输入不合法返回-1

示例一:

    输入
     3
     0
    输出
     153
    说明:153是第一个水仙花数
 示例二:
    输入
    9
    1
    输出
    -1
// 水仙花数
    public static void test070() {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        if (n < 3 || n > 7) {
            System.out.println(-1);
            return;
        }
        // 起始数
        int start = (int) Math.pow(10, n - 1);
        // 终止数
        int end = (int) Math.pow(10, n);
        List<Integer> reslist = new ArrayList<>();
        for (int i = start; i < end; i++) {
            int sum = 0;
            // 求每位数的简单解法
            // String[] split = (i + "").split("");
            // for (String s : split) {
            //     sum += Math.pow(Integer.parseInt(s), n);
            // }
            // 算出每位数
            List<Integer> list1 = singleNum(i);
            for (Integer s : list1) {
                // 每位数进行n次方并累加
                sum += Math.pow(s, n);
            }
            // 满足要求的放进结果集中
            if (sum == i) {
                reslist.add(i);
            }
        }
        if (m >= reslist.size()) {
            System.out.println(reslist.get(reslist.size() - 1) * m);
        } else {
            System.out.println(reslist.get(m));
        }
    }
    
    /**
     * 将一个整型数从后往前输出单个数字
     * @param num
     * @return
     */
    public static List<Integer> singleNum(int num){
        List<Integer> list = new ArrayList<>();
        while (num > 0) {
            int singleNum  = num % 10;
            list.add(singleNum);
            num = num /10;
        }
        return list;
    }

69.消除相邻且相同字母

 游戏规则:
  输入一个只包含英文字母的字符串,
  字符串中的两个字母如果相邻且相同,就可以消除。
  在字符串上反复执行消除的动作,
  直到无法继续消除为止,此时游戏结束。
  输出最终得到的字符串长度.
  输入描述:
  输入原始字符串str
  只能包含大小写英文字母,字母的大小写敏感,
  str长度不超过100
 
  输出描述
  输出游戏结束后,最终得到的字符串长度
 
  示例一:
  输入
  gg
  输出
  0
  说明 gg可以直接消除 得到空串 长度为0
 
  示例2
  输入:
  mMbccbc
  输出
  3
  说明mMbccbc中 可以先消除cc 此时变为mMbbc
  再消除 bb 此时变成mMc
  此时没有相同且相邻的字符 无法继续消除
  最终得到字符串mMc  长度为3
 
  备注:
  输入中包含非大小写英文字母时
  均为异常输入
  直接返回0
    // PS:字符串中的<两个>字母如果相邻且相同,就可以消除,相同的字符只能两两删除,比如有3个只能删2个
    // 消除相邻且相同字母
    public static void test069() {
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        // replaceAll 可以用正则表达式; [a-zA-Z]:匹配a-zA-Z其中一个
        //String newLine = line.replaceAll("[a-z]|[A-Z]", "");
        String newLine = line.replaceAll("[a-zA-Z]", "");
        // 异常输入
        if (newLine.length() > 0) {
            System.out.println(0);
            return;
        }
        for (int i = 0; i < line.length() - 1; i++){
            if (line.charAt(i) == line.charAt(i+1)) {
                // 两个字符相等,则消除
                line = line.replaceFirst(line.substring(i, i+2), "");
                // 需要把指针回到前一个字符
                if (i == 0){ 
                    i = i - 1; // 因为是开头,只需要-1抵消后面的i++
                } else {
                    i = i - 2; // -1回退到前一个字符,再-1抵消后面的i++
                }
            }
        }
//        System.out.println(line);
        System.out.println(line.length());

    }

更多华为od机试题请点这里<华为od机试题3 真题>,每篇8题,有更多的题也请告诉我啊

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chenzm666666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值