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↵
- 2 3 4 1↵
- 7 2 1 1↵
- no
- si
- 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:
- Orden de disposición de cuatro dígitos: como 2, 3, 4, 1 y 2, 4, 3, 1
- El orden de las operaciones de cuatro dígitos (cómo agregar paréntesis): como (2 + 3) - (4 + 1) y (2 + 3) -4 + 1
- Operación entre cuatro dígitos (3 operadores): como (2 + 3) - (4 + 1) y (2 + 3) - (4-1)
Cuente aproximadamente las 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:
- 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)
- 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)
- Seleccione los dos números restantes para realizar operaciones para obtener el resultado final y
- 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
-
¡La matriz de banderas debe inicializarse en cada ciclo! De lo contrario, se conservará el último resultado y esta vez se producirá el error
-
¡Recuerde omitir el caso en el que el divisor es 0 al enumerar las dos operaciones de división! De lo contrario, volverá
-
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
-
La matriz num debe almacenarse en doble, porque el valor medio se almacenará en el medio y habrá decimales
-
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 ~