Calcular 24 | Retroceder

Calcular 24

Los grados 10 hora de apertura Martes, 7 de abril de 2020 08:55
descuento 0,8 Tiempo de descuento Viernes, 1 de mayo de 2020 23:55
Se permite la presentación tardía No Hora de cierre Viernes, 1 de mayo de 2020 23:55

         Una baraja de cartas tiene 52 cartas además de los reyes grandes y pequeños, con cuatro cartas cada una del 1 al 13. Se requiere diseñar un programa. Para cuatro de las 52 tarjetas dadas al azar, use + - × ÷ cuatro operaciones para juzgar si cada número solo se puede usar una vez, pero no se puede usar, y se calcula 24. Tenga en cuenta que los 4 números dados están desordenados y se pueden agregar corchetes.

  Entrada de prueba Rendimiento esperado límite de tiempo Limite de memoria Proceso extra
Caso de prueba 1  
  1. 1 1 1 1↵
  2. 2 3 4 1↵
  3. 7 2 1 1↵
 
  1. no
  2. si
  3. si
1 segundo Los 64M 0

1. Análisis de problemas

Primero, enumere aproximadamente todas las situaciones posibles de operaciones de combinación de 4 dígitos. Los factores que pueden llevar a resultados diferentes son:

  1. Orden de disposición de cuatro dígitos: como 2, 3, 4, 1 y 2, 4, 3, 1
  2. El orden de las operaciones de cuatro dígitos (cómo agregar paréntesis): como (2 + 3) - (4 + 1) y (2 + 3) -4 + 1
  3. Operación entre cuatro dígitos (3 operadores): como (2 + 3) - (4 + 1) y (2 + 3) - (4-1) 

Cuente aproximadamente las  A {_ {4} ^ {4}} * 5 * 3 ^ 3 = 3888 especies, no enumerará el tiempo de espera. Pero hay muchas categorías, aquí está la principal necesidad de aclarar cómo buscar todas las situaciones , principalmente considere el método de retroceso, no importa si poda o poda ~


2. Ideas

       Primero veamos un pequeño detalle. A través de la observación, encontramos que el primer factor (orden de disposición diferente) es en realidad diferente (cuando los factores 2 y 3 son iguales), puede no tener ningún efecto, como: (2 + 3) - (4 + 1) y (3 + 2) - (1 + 4). De hecho:

La suma y la multiplicación no tienen nada que ver con la secuencia, y la resta y la división no tienen nada que ver con la secuencia. 


      Considerar los tres factores por separado hará que el retroceso sea muy complicado, y lo anterior también explica que cuando los factores 1 y 2 se enumeran por separado, habrá partes repetitivas, por lo que aquí consideramos combinar los factores 1 y 2 y considerar el tercer factor por separado. Entonces, la idea general del algoritmo es la siguiente:

  1. Seleccione dos números de los cuatro números para realizar la operación, el resultado de la operación es x, y aún quedan tres números por calcular (x y los dos números que no participan en la operación)
  2. Seleccione dos números de tres números para realizar operaciones. El resultado de la operación es x. En este momento, quedan dos números por calcular (x y un número que no está involucrado en la operación)
  3. Seleccione los dos números restantes para realizar operaciones para obtener el resultado final y
  4. Si y = 24, es decir, el resultado de esta selección es correcto y la salida es sí. De lo contrario, vuelva a seleccionar (si se seleccionan todos y el resultado es 24 y no se encuentra ningún resultado)

Parte de la consideración para la fusión de 1, 2 factores: El proceso de selección de tres es la fusión de todos los factores 1 y 2, incluidas todas las situaciones causadas por la diferencia entre los factores 1 y 2.

Consideraciones de 3 factores: correspondiente al proceso de realizar operaciones sobre los dos números seleccionados (desordenado) cada vez. Pero tenga en cuenta que aquí no solo se deben enumerar 4 tipos de operaciones, ¡sino 6 tipos! ¡Porque para todos los resultados de operaciones no ordenadas sobre dos números, la resta y la división deben enumerarse dos veces!


3. Implementación de algoritmos

       La implementación aquí utiliza inteligentemente el anidamiento de dos bucles y la marca de matriz de banderas para simular el proceso de selección, de modo que no sea redundante ni tenga fugas. Es más difícil de entender: las variables de bucle i y j representan respectivamente los dos números a buscar, y deben estar desmarcados (es decir, no han sido calculados, de lo contrario se saltará la selección de este bit). Nota: El resultado del cálculo de los dos números seleccionados aquí se almacena nuevamente en la posición de i, y el cálculo continúa. Y solo se marcará la posición j. Es decir, saca dos y guarda el resultado.

        Después de ingresar al cuerpo del bucle, se enumeran 6 operaciones para los dos números.

     (De hecho, el valor de cada paso del algoritmo de retroceso es el número de pasos correspondientes a las ideas del algoritmo enumeradas en 2 de este artículo).

Esta pregunta es un poco difícil de entender. De acuerdo con mi peinado y digestión del código, debería poder entenderlo rápidamente ~ El código de CA se publica a continuación:

//
// Created by A on 2020/4/29.
//
#include <cstdio>
#include <cmath>
#include <cstring>

#define DIF 0.0000001

bool flag[5] = {false};   //标记该位是否被计算过
double num[5] = {0};   //每一位的值

bool Calc24(int step) {
    if (step == 4) {
        for (int i = 0; i < 4; i++)  //结果可能在1、2、3、4位中(取决于运算的顺序)
            if (!flag[i] && fabs(num[i] - 24) <= DIF)  //剩余位上(结果)的值几乎为24
                return true;
        return false;
    }

    for (int i = 1; i <= 4; i++)
        if (!flag[i])
            for (int j = i + 1; j <= 4; j++) {
                if (!flag[j]) {
                    double temp1 = num[i], temp2 = num[j];  //分别取出待运算的两位
                    flag[j] = true;   //由于计算结果储存在第 i 位可以继续参与运算,而第 j 位不再继续

                    /* 分别搜索:两种数的 6 种运算 */
                    num[i] = temp1 + temp2;
                    if (Calc24(step + 1))
                        return true;

                    num[i] = temp1 - temp2;
                    if (Calc24(step + 1))
                        return true;

                    num[i] = temp1 * temp2;
                    if (Calc24(step + 1))
                        return true;

                    if (temp2 != 0) {   //排除分母为零的情况
                        num[i] = temp1 / temp2;
                        if (Calc24(step + 1))
                            return true;
                    }

                    num[i] = temp2 - temp1;
                    if (Calc24(step + 1))
                        return true;

                    if (temp1 != 0) {   //排除分母为零的情况
                        num[i] = temp2 / temp1;
                        if (Calc24(step + 1))
                            return true;
                    }

                    /* 还原,便于回溯 */
                    num[i] = temp1;
                    flag[j] = false;
                }
            }
    return false;  //一直没有出口
}

int main() {
    while (EOF != scanf("%lf %lf %lf %lf", &num[1], &num[2], &num[3], &num[4])) {
        memset(flag, false, 5 * sizeof(bool));   //一定注意初始化
        if (Calc24(1))
            printf("yes\n");
        else
            printf("no\n");
    }
}

4. Resumen de puntos propensos a errores

  1.  ¡La matriz de banderas debe inicializarse en cada ciclo! De lo contrario, se conservará el último resultado y esta vez se producirá el error

  2. ¡Recuerde omitir el caso en el que el divisor es 0 al enumerar las dos operaciones de división! De lo contrario, volverá

  3. Cuando el paso = 4 es el resultado del juicio, se debe juzgar si el bit de resultado es 24 (solo el indicador del bit de resultado es falso en este momento); de lo contrario, se puede juzgar como sí si el resultado intermedio aparece como 24. Si no comprende esto, puede probar este caso de uso: 3 4 2 3. El resultado correcto es no. Fui el último caso de uso debido a esto

  4. La matriz num debe almacenarse en doble, porque el valor medio se almacenará en el medio y habrá decimales

  5. La determinación de si el resultado es igual a 24 es la determinación de números de coma flotante, porque el cálculo de números de coma flotante no puede ser completamente exacto y algunos errores deben eliminarse. Así que no juzgues directamente con 24, pero la diferencia con 24 es pequeña.

 



Si te ayuda, dale me gusta ~

Supongo que te gusta

Origin blog.csdn.net/weixin_43787043/article/details/105847797
Recomendado
Clasificación