算法:小记两道牛客的算法题

2023-03-13  本文已影响0人  南风知我咦

问题

1.合法最小数

2.开心消消乐

错误或者说不完善的方案
    static int result = 0;//最终点击次数
    static int count = 0;//当前节点附近包括它自己1的总数
    static int indexI = 0;
    static int indexJ = 0;
    static int n, m;

    public static void userSetZero() {
        int[][] inputs;
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        m = in.nextInt();
        inputs = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                inputs[i][j] = in.nextInt();
            }
        }
        //new int[][]{{1, 1, 1}, {0, 1, 0}, {0, 1, 0}}
        setZero(inputs);
        System.out.println("需要点击" + result + "次");
    }

    //1 1 1
    //0 1 0
    //0 1 0
    public static void setZero(int[][] inputs) {
        count = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int ij = inputs[i][j];
                int countIJ = 0;
                if (inputs[i][j] == 1) {//当前点位为1
                    countIJ++;
                    //正上
                    if (i - 1 >= 0 && inputs[i - 1][j] == 1) countIJ++;
                    //正右
                    if (j + 1 < m && inputs[i][j + 1] == 1) countIJ++;
                    //正下
                    if (i + 1 < n && inputs[i + 1][j] == 1) countIJ++;
                    //正左
                    if (j - 1 >= 0 && inputs[i][j - 1] == 1) countIJ++;
                    //坐上
                    if (i - 1 >= 0 && j - 1 >= 0 && inputs[i - 1][j - 1] == 1)
                        countIJ++;
                    //右上
                    if (i - 1 >= 0 && j + 1 < m && inputs[i - 1][j + 1] == 1)
                        countIJ++;
                    //右下
                    if (i + 1 < n && j + 1 < m && inputs[i + 1][j + 1] == 1)
                        countIJ++;
                    //左下
                    if (i + 1 < n && j - 1 >= 0 && inputs[i + 1][j - 1] == 1)
                        countIJ++;

                }
                if (count < countIJ) {
                    count = countIJ;
                    indexI = i;
                    indexJ = j;
                }
            }
        }

        //找到了周围1最多的点,把它和它周围的点都设置为0
        if (count != 0) {
            setPointZero(indexI, indexJ, inputs);
            result++;
        }
        if (count == 0) return;
        setZero(inputs);
    }

    //递归调用把[x,y]点和它周围和它周围的周围的1设置为0
    public static void setPointZero(int x, int y, int[][] inputs) {
        inputs[x][y] = 0;
        //正上
        if (x - 1 >= 0 && inputs[x - 1][y] == 1) setPointZero(x - 1, y, inputs);
        //正右
        if (y + 1 < m && inputs[x][y + 1] == 1) setPointZero(x, y + 1, inputs);
        //正下
        if (x + 1 < n && inputs[x + 1][y] == 1) setPointZero(x + 1, y, inputs);
        //正左
        if (y - 1 >= 0 && inputs[x][y - 1] == 1) setPointZero(x, y - 1, inputs);
        //坐上
        if (x - 1 >= 0 && y - 1 >= 0 && inputs[x - 1][y - 1] == 1)
            setPointZero(x - 1, y - 1, inputs);
        //右上
        if (x - 1 >= 0 && y + 1 < m && inputs[x - 1][y + 1] == 1)
            setPointZero(x - 1, y + 1, inputs);
        //右下
        if (x + 1 < n && y + 1 < m && inputs[x + 1][y + 1] == 1)
            setPointZero(x + 1, y + 1, inputs);
        //左下
        if (x + 1 < n && y - 1 >= 0 && inputs[x + 1][y - 1] == 1)
            setPointZero(x + 1, y - 1, inputs);
    }
真正的方案,只要递归调用就好了
    static int result = 0;
    static int count = 0;
    static int indexI = 0;
    static int indexJ = 0;
    static int n, m;

    public static void userSetZero() {
        int[][] inputs;
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        m = in.nextInt();
        inputs = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                inputs[i][j] = in.nextInt();
            }
        }
        //new int[][]{{1, 1, 1}, {0, 1, 0}, {0, 1, 0}}
        // 1 1 1 1
        // 0 0 0 1
        // 1 1 0 0
        // 1 1 0 1
        setZero2(inputs);
        System.out.println("需要点击" + result + "次");
    }

    public static void setZero2(int[][] inputs){
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (inputs[i][j] == 1) {
                    setPointZero(i, j, inputs);
                    result++;
//                    setZero(inputs);
                }
            }
        }
    }
    //递归调用把[x,y]点和它周围和它周围的周围的1设置为0
    public static void setPointZero(int x, int y, int[][] inputs) {
        inputs[x][y] = 0;
        //正上
        if (x - 1 >= 0 && inputs[x - 1][y] == 1) setPointZero(x - 1, y, inputs);
        //正右
        if (y + 1 < m && inputs[x][y + 1] == 1) setPointZero(x, y + 1, inputs);
        //正下
        if (x + 1 < n && inputs[x + 1][y] == 1) setPointZero(x + 1, y, inputs);
        //正左
        if (y - 1 >= 0 && inputs[x][y - 1] == 1) setPointZero(x, y - 1, inputs);
        //坐上
        if (x - 1 >= 0 && y - 1 >= 0 && inputs[x - 1][y - 1] == 1)
            setPointZero(x - 1, y - 1, inputs);
        //右上
        if (x - 1 >= 0 && y + 1 < m && inputs[x - 1][y + 1] == 1)
            setPointZero(x - 1, y + 1, inputs);
        //右下
        if (x + 1 < n && y + 1 < m && inputs[x + 1][y + 1] == 1)
            setPointZero(x + 1, y + 1, inputs);
        //左下
        if (x + 1 < n && y - 1 >= 0 && inputs[x + 1][y - 1] == 1)
            setPointZero(x + 1, y - 1, inputs);
    }

总结

上一篇 下一篇

猜你喜欢

热点阅读