zoukankan      html  css  js  c++  java
  • 2020/9/1拼多多笔试

    1. 第一题
    /*
    * 题目描述
    * ------------
    * |  2 | 1
    * |3   |   8
    * |-----------
    * |4   |   7
    * |  5 | 6
    * |-----------
    * 有一个NxN的矩阵,把里面的(i,j)划分都上述8个区域,米字处(横竖中线、斜线)为0
    *
    * */
    import java.util.Scanner;
    public class Main1 {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            int n = scanner.nextInt();
            scanner.close();
    
            int [][] arr = new int[n][n];
            double mid = (n-1)/2.0;//中线
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    //23
                    if (i< mid && j<mid ){
                        if (i<j) arr[i][j] = 2;
                        else if (i>j)arr[i][j] = 3;
                    }
                    //45
                    else if (i>mid && j<mid ){
                        if (n-1-i>j)arr[i][j]=4;
                        else if (n-1-i<j)arr[i][j]=5;
                    }
                    //18
                    else if (i<mid && j>mid ){
                        if (n-1-i>j)arr[i][j]=1;
                        else if (n-1-i<j)arr[i][j]=8;
                    }
                    //67
                    else if (i>mid && j>mid ){
                        if (i>j)arr[i][j]=6;
                        else if (i<j)arr[i][j]=7;
                    }
                }
            }
    
            for (int i = 0; i <n ; i++) {
                for (int j = 0; j <n-1 ; j++) {
                    System.out.print(arr[i][j]);
                    System.out.print(" ");
                }
                System.out.println(arr[i][n-1]);
            }
        }
    }
    
    /*
    示例:
    input: 10
    output:
    0 2 2 2 2 1 1 1 1 0
    3 0 2 2 2 1 1 1 0 8
    3 3 0 2 2 1 1 0 8 8
    3 3 3 0 2 1 0 8 8 8
    3 3 3 3 0 0 8 8 8 8
    4 4 4 4 0 0 7 7 7 7
    4 4 4 0 5 6 0 7 7 7
    4 4 0 5 5 6 6 0 7 7
    4 0 5 5 5 6 6 6 0 7
    0 5 5 5 5 6 6 6 6 0
    * */
    
    1. 第二题
    /**
     * 题目描述
     * 有一个NxM矩阵,矩阵有值只有0和1, 1代表一个人,相邻的人(只包含上下左右相邻)为一组。
     * 现在请移动其中一个人,移动后使一个团队的人数尽可能大,求这个最大的值。
     * 如:
     * 4 4
     * 1 0 1 1
     * 1 1 0 1
     * 0 0 0 0
     * 1 1 1 1
     *
     * 可以把(0,2)移动到(2,0):
     * 4 4
     * 1 0 0 1
     * 1 1 0 1
     * 1 0 0 0
     * 1 1 1 1
     * 形成一个8人的组,是所有移动方案中最大的。
     *
     * 我的解题思路是:
     *   设置一个最大组人数值max,对于每一个0位置,尝试将该位置置1,然后以该位置为入口dfs进入改组,计算人数,更新max,
     *   dfs遍历的同时会将该组全部置-1。再次dfs把-1还原为1。
     *   尝试将所有0变为1后,会得到更新后的max,这个max可能需要-1:
     *         如果移动后只有一组,那个这个移动的元素是内部移动,不能从其他组来,所以需要-1
     *         判断方式: dfs把最大组置-1,然后访问整个数组,如果还存在1,说明多个组,返回max;否则,返回max-1
     */
    public class Main2 {
        private int[][] arr;
        private int row;
        private int col;
    
        public Main2() {
            Scanner scanner = new Scanner(System.in);
            row = scanner.nextInt();
            col = scanner.nextInt();
            arr = new int[row][col];
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    arr[i][j] = scanner.nextInt();
                }
            }
            scanner.close();
    
            int max = 0; //最大组人数
            int maxi = 0, maxj = 0; //记录最大组的一个元素下标
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    if (arr[i][j] == 0) {
                        arr[i][j] = 1; //尝试把0的地方填1
                        int num = dfs(i, j,arr); //dfs遍历得到该组的人数,同时会将改组全部变为-1
                        if (num > max) {
                            max = num; //更新最大值
                            maxi = i; //更新最大组入口元素下标
                            maxj = j;
                        }
                        recover(i, j,arr); //把该组从-1还原为1
                        arr[i][j] = 0; //还原该位置的0
                    }
                }
            }
    
            dfs(maxi, maxj,arr); //从入口访问最大组,将该组全部置-1
    
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    if (arr[i][j]==1){  //还有其他元素是1,表明现在不止一个组,那么那个填充1的0位置,可以是其他组移动过来的
                        System.out.println(max);
                        return;
                    }
                }
            }
            //上面没有返回,说明移动后只有一个组,移动的这个元素也属于本组,于是需要减出来。
            System.out.println(max-1);
        }
    
    
        //从[i,j]处进入一个组,统计其人员数,并在访问过程中全部置-1;
        int dfs(int i, int j, int[][]arr) {
            if (i < 0 || i >= arr.length || j < 0 || j >= arr[0].length || arr[i][j] == 0 || arr[i][j] == -1) return 0;
            arr[i][j] = -1;
            return 1 +
                    dfs(i, j + 1,arr) +
                    dfs(i, j - 1,arr) +
                    dfs(i - 1, j,arr) +
                    dfs(i + 1, j,arr);
        }
        //从[i,j]处进入一个组, 访问全组,将dfs改变的-1还原为1
        void recover(int i, int j,int arr[][]) {
            if (i < 0 || i >= arr.length || j < 0 || j >= arr[0].length || arr[i][j] !=-1) return;
            arr[i][j] = 1;
            recover(i, j + 1,arr);
            recover(i, j - 1,arr);
            recover(i - 1, j,arr);
            recover(i + 1, j,arr);
        }
    
    
        public static void main(String[] args) {
            Main2 main = new Main2();
        }
    }
    /*
    示例:
    input:
    4 4
    1 0 1 1
    1 0 1 1
    0 1 0 0
    1 1 1 1
    output:
    12
    */
    
    1. 第三题
    /*
    * 题目描述:
    * 输入一个数N,大小为M的数组Arr。
    * 对于一个数X,如果X能被Arr中的某个数整除,则成X是‘特殊的’
    * 对于1~N,判断其中有多少数是‘特殊的’
    *
    * 可以直接暴力,如下,但是会超时。
    * 使用一些优化方法:
    * 1. 记录数组中的最大、小值,1~N遍历时 从最小值开始,到最大值时结束。
    * 2. 遍历1~N时可以判断是否是素数。
    * 3. 不知道还有没有其他优化方法或者更好的解法???
    * */
    public class Main4 {
        private int M;
        private int N;
        private int[] arr;
    
        public Main4() {
            Scanner scanner = new Scanner(System.in);
            N = scanner.nextInt();
            M = scanner.nextInt();
            arr = new int[N];
            for (int i = 0; i < M; i++) {
                arr[i] = scanner.nextInt();
            }
            scanner.close();
            int res = 0;
            for (int i = 1; i <= N; i++) {
                for (int a : arr) {
                    if (i % a == 0) {
                        res++;
                        break;
                    }
                }
            }
    
            System.out.println(res);
        }
    }
    
    1. 第四题
    /*
    * 题目描述
    * 背包问题:初始背包容量M
    * 有N个商品:
    *   每个商品:容量(正负,为负表示可以增加背包容量) 、利益(正负)
    * 现在选择商品装到背包,使总利益最大
     * 这题是01背包问题的改编。
     * 01背包问题中商品的体积全部是正,这里可以是负数,表示增大背包空间
    * */
    
  • 相关阅读:
    git 分支建立及合并
    git push 冲突
    Ubuntu 16.04下安装64位谷歌Chrome浏览器
    Nginx+uswgi+Django部署
    Deepin下python安装uwsgi报错: Python.h:没有那个文件或目录
    Deepin系统更新apt-get源
    语义化的理解
    尝试Vue3.0
    Vue3.0响应式实现
    Vue2.0响应式原理以及重写数组方法
  • 原文地址:https://www.cnblogs.com/XT-xutao/p/13598998.html
Copyright © 2011-2022 走看看