Copa Lanqiao 2023 14a Competencia Provincial Preguntas reales: colocación de píxeles

Tabla de contenido

Copa Lanqiao 2023 14a Competencia Provincial Preguntas reales: colocación de píxeles

Descripción de la pregunta

Formato de entrada

Formato de salida

Entrada de muestra

Salida de muestra

pista

[Análisis de ideas]

【Código】


Si crees que sabes escribir bien, puedes unirte al grupo QQ 907575059.

Copa Lanqiao 2023 14a Competencia Provincial Preguntas reales: colocación de píxeles

Límite de tiempo: 3 s Límite de memoria: 320 MB Envíos: 72 Resuelve: 30

Descripción de la pregunta

Xiaolan se ha obsesionado recientemente con un juego llamado "Colocación de píxeles", que se juega en un tablero de ajedrez con una cuadrícula de n × m, que contiene n filas y cada fila contiene m cuadrados. La tarea del jugador es llenar estos cuadrados de n × m con píxeles, y los colores de relleno son solo blanco o negro. En algunos cuadrados aparecerá un número entero x (0 ≤ x ≤ 9), lo que significa que el cuadrado actual más los cuadrados circundantes en ocho direcciones (respectivamente, arriba, abajo, izquierda, derecha y superior izquierda, superior derecha, inferior izquierda). , abajo a la derecha), solo hay x cuadrados del total de nueve cuadrados que deben rellenarse con negro.

Los jugadores deben llenar la cuadrícula con píxeles y al mismo tiempo cumplir con todas las restricciones digitales. Por favor ayuda a Xiaolan a completarlo. La pregunta garantiza que todos los datos tengan soluciones y que las soluciones sean únicas.

Formato de entrada

La primera línea de entrada contiene dos números enteros n, m, separados por un espacio, que indica el tamaño del tablero de ajedrez.

Las siguientes n líneas, cada una de las cuales contiene m caracteres, representan el diseño del tablero de ajedrez. El carácter puede ser los números del 0 al 9, que representan números en la cuadrícula, o el carácter puede ser un guión bajo (código ASCII 95), que representa una cuadrícula normal sin números.

Formato de salida

Genere n líneas, cada línea contiene m caracteres, que representan la respuesta. Si la cuadrícula está llena de blanco, utilice el carácter 0.

Representado por el carácter 1 si la cuadrícula está llena de negro.

Entrada de muestra

Copiar

6 8 
_1__5_1_ 
1_4__42_ 
3__6__5_ 
___56___ 
_688___4 
_____6__

Salida de muestra

Copiar

00011000 
00111100 
01000010 
11111111 
01011110 
01111110

pista

Copa Lanqiao 2023 14a Competencia Provincial Preguntas reales: colocación de píxeles

El lado izquierdo de la imagen de arriba es el diseño del tablero de ajedrez correspondiente a los datos de muestra, y el lado derecho de la imagen de arriba es la solución de este juego. Por ejemplo, hay un número 3 en el cuadrado de la fila 3, columna 1, y solo hay tres cuadrados a su alrededor llenos de negro, a saber, fila 3, columna 2, fila 4, columna 1 y fila 4, columna 1. 2 cuadrícula de columnas.

Para el 50% de los casos de evaluación, 1 ≤ n, m ≤ 5;

Para todos los casos de evaluación, 1 ≤ n, m ≤ 10.

[Análisis de ideas]

Dado que esta pregunta es de tamaño pequeño y tiene una sola respuesta, se puede utilizar una estrategia de búsqueda para descartar una gran cantidad de posibilidades.

1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 0 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1
1

Al buscar en la tabla de píxeles, de izquierda a derecha y de arriba a abajo, cualquier posición i, j (la posición marcada en rojo). Las posiciones azules arriba definitivamente no se verán afectadas por decisiones futuras. Podemos comenzar directamente a juzgar si estas posiciones azules cumplen con las reglas numéricas de la pregunta. De lo contrario, podemos abandonar una gran cantidad de posibilidades posteriores y acortar el tiempo de búsqueda. Cuando se complete se juzgará si la tabla total está llena o no, si se cumple se abandonará directamente la búsqueda posterior, porque la respuesta es única.

【Código】

package LQB;

import java.util.Scanner;

/**
 * @ProjectName: study3
 * @FileName: Ex8
 * @author:HWJ
 * @Data: 2023/9/18 23:40
 */
public class Ex8 {
    static int[][] ans;
    static int[][] map;
    static int n;
    static int m;
    static int[][] uses;
    static boolean flag = false;

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        n = input.nextInt();
        m = input.nextInt();
        map = new int[n][m];
        ans = new int[n][m];
        uses = new int[n][m];

        for (int i = 0; i < n; i++) {
            String str = input.next();
            char[] chars = str.toCharArray();
            for (int j = 0; j < m; j++) {
                map[i][j] = chars[j] == '_' ? Integer.MAX_VALUE : (chars[j] - '0');
            }
        }
        dfs(0,0);


    }

    public static void add(int i, int j) { // 统计当前数组的数字,为方便判断
        uses[i][j]++;
        if (j + 1 < m) {
            uses[i][j + 1]++;
        }
        if (j - 1 >= 0) {
            uses[i][j - 1]++;
        }
        if (i - 1 >= 0) {
            uses[i - 1][j]++;
            if (j - 1 >= 0) {
                uses[i - 1][j - 1]++;
            }
            if (j + 1 < m) {
                uses[i - 1][j + 1]++;
            }
        }
        if (i + 1 < n) {
            uses[i + 1][j]++;
            if (j - 1 >= 0) {
                uses[i + 1][j - 1]++;
            }
            if (j + 1 < m) {
                uses[i + 1][j + 1]++;
            }
        }
    }

    public static void del(int i, int j) { // 如果数组在i,j位置不能放1,就改为0,并删除他的信息
        uses[i][j]--;
        if (j + 1 < m) {
            uses[i][j + 1]--;
        }
        if (j - 1 >= 0) {
            uses[i][j - 1]--;
        }
        if (i - 1 >= 0) {
            uses[i - 1][j]--;
            if (j - 1 >= 0) {
                uses[i - 1][j - 1]--;
            }
            if (j + 1 < m) {
                uses[i - 1][j + 1]--;
            }
        }
        if (i + 1 < n) {
            uses[i + 1][j]--;
            if (j - 1 >= 0) {
                uses[i + 1][j - 1]--;
            }
            if (j + 1 < m) {
                uses[i + 1][j + 1]--;
            }
        }
    }


    static boolean check(int x, int y) { // 检查当前的数组是否满足要求
        // 检查的地方已经不可能被以后的策略影响
        for (int i = 0; i <= x - 2; i++) {
            for (int j = 0; j < m; j++) {
                if (map[i][j] == Integer.MAX_VALUE) continue;
                if (uses[i][j] != map[i][j]) {
                    return false;
                }
            }
        }
        if (x >= 1)
            for (int j = 0; j <= y - 2; j++) {
                if (map[x - 1][j] == Integer.MAX_VALUE) continue;
                if (uses[x - 1][j] != map[x - 1][j]) return false;
            }
        return true;
    }

    // 当做完整个数组的决策后,对数组的所有地方进行检查
    static boolean check2() {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (map[i][j] == Integer.MAX_VALUE) continue;
                if (uses[i][j] != map[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }


    // i,j 表示现在遍历到那个位置了。
    public static void dfs(int i, int j) {

        if (flag) {
            return;
        }
        if (i == n) {
            if (!check2()) return;
            for (int x = 0; x < n; x++) {
                for (int y = 0; y < m; y++) {
                    System.out.print(ans[x][y]);
                }
                System.out.println();
            }
            flag = true; // 因为答案是唯一的,所以只要找到一个答案,就立刻退出搜索
            return;
        }

        if (!check(i, j)) return; // 检查当前的棋盘是否满足部分要求


        // 对每一种可能性进行搜索。
        if (j == m - 1) {
            ans[i][j] = 1;
            add(i,j);
            dfs(i + 1, 0);
            ans[i][j] = 0;
            del(i,j);
            dfs(i + 1, 0);
            return;
        }
        ans[i][j] = 1;
        add(i,j);
        dfs(i, j + 1);
        ans[i][j] = 0;
        del(i,j);
        dfs(i, j+ 1);
        return;
    }
}

Supongo que te gusta

Origin blog.csdn.net/weixin_73936404/article/details/133031595
Recomendado
Clasificación