• 部门优化和邀请码检测面试题——Java解法


    部门优化

    某公司内有 4 个项⽬组,项⽬组 A、B、C、D,项⽬组A现有10人,项⽬组B现有7人,项⽬组C现 有5人,项⽬组D现有4人。为了实现跨项⽬组协作,公司决定每⽉从⼈数最多的项⽬组中抽调 3 ⼈ 出来,到其他剩下 3 组中,每组 1 人,这称之为一次调整优化(亦即经过第⼀次调整后,A组有7 人,B组有8人,C组有6人,D组有5人)。 那么请问,经过十年的优化调整后,各项目组各有几人? 编程求解该问题,并思考是否为最优解。

    解题思路

    最直观的解题思路就是,每次都进行一次优化,根据优化规则一直优化120次。

    每次优化其实就是从数组中选出最大值,然后最大值-3,其他元素+1。

    代码逻辑实现:

    public class Solution {
        public static void main(String[] args) {
            test1();
        }
    
        public static void test1(){
            //初始数组
            int[] arr={10,7,5,4};
    		//一个月优化一次,十年一共120次
            for (int i = 0; i <120 ; i++) {
                arr=optimize(arr);
            }
            //打印优化十年后的结果
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i]+" ");
            }
    
        }
    
        /**
         * 优化的逻辑
         * @param arr 目标数组
         * @return 优化后的数组
         */
        private static int[] optimize(int[] arr){
            int index=getMaxIndex(arr);
            for (int i = 0; i < arr.length; i++) {
                if(index==i){
                    arr[i]-=3;
                }else{
                    arr[i]+=1;
                }
            }
            return arr;
        }
    
        /**
         * 获取数组最大值的索引
         * @param arr 目标数据
         * @return 最大值的索引
         */
        private static int getMaxIndex(int [] arr){
            int max=0;
            int index=0;
            for (int i = 0; i < arr.length; i++) {
                if(arr[i]>max){
                    max=arr[i];
                    index=i;
                }
            }
            return index;
        }
    }
    

    总结规律之后发现,这个并非最优解。前几次的结果如下所示:

    优化1次:10 7 5 4

    优化2次:7 8 6 5

    优化3次:8 5 7 6

    优化4次:5 6 8 7

    优化5次:6 7 5 8

    优化6次:7 8 6 5

    此后的结果一直在7,8,6,5之间变换。除去第一次的结果,从第二次开始每4个数据之后开始重复。也就是说一共119次优化,前116次优化之后结果为7 8 6 5,再优化三次,得出结果为6 7 5 8。

    邀请码检测

    某产品的⽤户注册邀请码为⼀串有⼩写字⺟和数字组成的字符串,字符串⻓度为16。当⽤户数据邀 请码的时候,系统需要对邀请码做有效性验证,假设验证规则如下: 1、 从序列号最后⼀位字符开始,逆向将奇数位(1、3、5等等)相加; 2、从序列号最后⼀位数字开始,逆向将偶数位数字,先乘以2(如果乘积为两位数,则将其减去 9),再求和; 3、将奇数位总和加上偶数位总和,结果可以被10整除; 4、⼩写字⺟对应数值,可由下⾯键值对确定; [(a,1), (b,2), (c,3)…,(i,9), (j,1), (k, 2)…],亦即,按字⺟顺序,1-9循环。 输⼊:输⼊16位字符串,表示邀请码 输出:输出“ok”或者“error”

    解题思路

    这个题真没什么好说的,按题目做就行了。主要是要知道ASCLL码对应的值

    public class inviteCodeSolution {
        public static void main(String[] args) {
            String s = "123456789123456C";
            System.out.println(isVerify(s));
        }
    
        /**
         * 对校验结果进行格式化
         * @param s 传入的邀请码
         * @return 如果合法则为ok,否则为error
         */
        public static String isVerify(String s) {
            boolean result = false;
            try {
                result = verify(s);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result ? "ok" : "error";
        }
    
        /**
         * 校验邀请码是否合法
         * @param s 传入的邀请码
         * @return true合法,false不合法
         * @throws Exception 传入的数据包含除数字和小写字母以外的字符
         */
        public static boolean verify(String s) throws Exception {
            char[] chars = s.toCharArray();
            int sumOdd = 0, sumEven = 0;
            //逆序遍历
    
            for (int i = chars.length - 1; i >= 0; i--) {
                //如果是偶数位
                if (i % 2 == 0) {
    
                    sumEven += getMapData(chars[i]) > 4 ? ((getMapData(chars[i]) * 2) - 9) : (getMapData(chars[i]) * 2);
    
                } else {
                    //奇数位
                    sumOdd += getMapData(chars[i]);
                }
            }
    
            System.out.println("偶数和:" + sumEven + ",奇数和:" + sumOdd);
            return (sumEven + sumOdd) % 10 == 0;
        }
    
        /**
         * 获取映射的值
         *
         * @param c 传入的字符
         * @return c的实际值
         */
        public static int getMapData(char c) throws Exception {
            int result;
            //如果是小写字母,则按规则映射成数字
            if (c >= 97 && c <= 122) {
                result = (c - 96) % 9;
            } else if (c >= 48 && c <= 57) {
                result = c - 48;
            } else {
                //非数字和小写字母则抛出异常
                throw new Exception("数据错误");
            }
            return result;
        }
    }
    
  • 相关阅读:
    svn安装教程
    六、数组类的创建
    五、顺序存储线性表分析
    四、StaticList 和 DynamicList
    三、顺序存储结构的抽象实现
    二、线性表的顺序存储结构
    一、线性表的本质和操作
    专题五:局部变量、全局变量global、导入模块变量
    专题四:文件基础知识、字符编码
    专题3-2:列表基础知识:二维list排序、获取下标和处理txt文本实例
  • 原文地址:https://www.cnblogs.com/rever/p/13787008.html
Copyright © 2020-2023  润新知