#携程笔试# 20220830

四题AC(JAVA版)分享给大家

第一题
坑点在于要求不能有前导零 && 所有数字都要参与排列。最开始以为凑成偶数,自动去掉前导零就得了。。。
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int q = sc.nextInt();
        for(int i = 0; i < q; i++){
            int x = sc.nextInt();
            if((x & 1) == 0){
                System.out.println(x);
                continue;
            }
            if (x < 10){
                System.out.println(-1);
                continue;
            }
            String str = String.valueOf(x);
            StringBuilder sb = new StringBuilder();
            for (int j = 0; j < str.length(); j++){
                int num = str.charAt(j) - '0';
                if(j + 1 < str.length() && (num & 1) == 0 && str.charAt(j + 1) != '0'){
                    sb.append(str.substring(j + 1));
                    sb.append(num);
                    break;
                }else{
                    sb.append(num);
                }
            }
            if (str.equals(sb.toString())){
                System.out.println(-1);
                continue;
            }
            System.out.println(sb);
        }
    }

第二题
贪心:先计算 you 的个数 * 2,再对剩余的连续 n 个 o,取 n - 1 分。注意对 n < 2 的情况特殊处理。
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int q = sc.nextInt();
        sc.nextLine();
        for (int i = 0; i < q; i++){
            String[] split = sc.nextLine().split(" ");
            int a = Integer.parseInt(split[0]), b = Integer.parseInt(split[1]), c = Integer.parseInt(split[2]);
            int ans = Math.min(a, Math.min(b, c));
            b -= ans;
            ans *= 2;
            ans += b >= 2 ? b - 1 : 0;
            System.out.println(ans);
        }
    }

第三题
建图,认为当前节点及孩子节点的 r g b 个数大于 0 && 除该子树外的其他节点的 r g b 之和也大于0,则满足两个连通块各恰有三种颜色。
dfs
坑点在于题目未指出根节点,所以需双向建图 && 使用 visit 数组记录已访问节点。而树作为连通图,从任意节点开始遍历都可以了。
    static int ans = 0;
    static int r, g, b;
    static boolean[] vis;
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        scanner.nextLine();
        String str = scanner.nextLine();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c == 'r') r += 1;
            if (c == 'g') g += 1;
            if (c == 'b') b += 1;
        }

        // build tree
        ArrayList<Integer>[] nodeMap = new ArrayList[n];
        for (int i = 0; i < n; i++) {
            nodeMap[i] = new ArrayList<>();
        }

        for (int i = 1; i < n; i++) {
            int x = scanner.nextInt() - 1;
            int y = scanner.nextInt() - 1;
            nodeMap[x].add(y);
            nodeMap[y].add(x);
        }

        vis = new boolean[n];
        dfs(str, nodeMap, 0);
        System.out.println(ans);
    }

    public static ChildColorNumber dfs(String str, ArrayList<Integer>[] nodeMap, int node) {
        vis[node] = true;
        ArrayList<Integer> children = nodeMap[node];
        ChildColorNumber colorNumber = new ChildColorNumber();

        for (Integer child : children) {
            if (vis[child]) continue;
            ChildColorNumber ccn = dfs(str, nodeMap, child);
            if (ccn.red > 0 && ccn.green > 0 && ccn.blue > 0 && ccn.red < r && ccn.green < g && ccn.blue < b) ans += 1;
            colorNumber.red += ccn.red;
            colorNumber.green += ccn.green;
            colorNumber.blue += ccn.blue;
        }
        if (str.charAt(node) == 'r') colorNumber.red += 1;
        if (str.charAt(node) == 'g') colorNumber.green += 1;
        if (str.charAt(node) == 'b') colorNumber.blue += 1;
        return colorNumber;
    }
}

class ChildColorNumber {
    public int red;
    public int green;
    public int blue;

    public ChildColorNumber() {
        this.red = 0;
        this.blue = 0;
        this.green = 0;
    }
}
第四题

计算包括当前节点之前的任意两相邻数差的绝对值的最大值、再记录包括当前节点之后的任意两相邻数差的绝对值的最大值。
暴力遍历每一个节点,对其作平滑处理:将该节点改成左右两点平均值后的绝对值最大值。再取三者最大值即为修改当前节点所能得到的平滑值。
最后取最小的平滑值。
算是暴力了。。。
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] array = new int[n];
        int[] pre = new int[n];
        int[] suc = new int[n];
        for (int i = 0; i < n; i++) {
            array[i] = scanner.nextInt();
        }
        int ans = Integer.MAX_VALUE;
        for (int i = 1; i < n; i++) {
            pre[i] = Math.abs(array[i] - array[i - 1]);
            if (pre[i] < pre[i - 1]) pre[i] = pre[i - 1];
        }

        for (int i = n - 2; i >= 0; i--) {
            suc[i] = Math.abs(array[i] - array[i + 1]);
            if (suc[i] < suc[i + 1]) suc[i] = suc[i + 1];
        }

        for (int i = 0; i < n; i++){
            int pre_val = i > 0 ? pre[i - 1] : 0;
            int suc_val = i < n - 1 ? suc[i + 1] : 0;
            int mid = (i > 0 && i < n - 1) ? (Math.abs(arr[i - 1] - arr[i + 1]) + 1) / 2 : 0;

            mid = Math.max(mid, Math.max(pre_val, suc_val));
            ans = Math.min(ans, mid);
        }
        System.out.println(ans);


    }        




#携程笔试#
全部评论
菜鸡还在想着怎么解题,巨佬的代码都体现出优化
点赞 回复 分享
发布于 2022-08-30 23:22 江苏
大佬最后syso要写for循环外面
点赞 回复 分享
发布于 2022-08-31 09:17 黑龙江
u和v谁是父亲,谁是孩子不一定,所以要双向建图,这是最坑的
点赞 回复 分享
发布于 2022-08-31 09:20 吉林
请问大佬第一题所有数字都要参与排列是什么意思呢?我是找到一个偶数位就换到队尾,这样只过了50%
点赞 回复 分享
发布于 2022-08-31 14:16 辽宁

相关推荐

专心打鱼:互联网搬运工,贴子都要偷
点赞 评论 收藏
分享
头像
11-09 17:30
门头沟学院 Java
TYUT太摆金星:我也是,好几个华为的社招找我了
点赞 评论 收藏
分享
9 19 评论
分享
牛客网
牛客企业服务