HDU1016 - Problema del anillo de números primos

Problema de anillo de números primos HDU1016

1. Enlace de tema

HDU1016

2. Contenido del tema

Un anillo se compone de n círculos como se muestra en el diagrama. Ponga el número natural 1, 2,…, n en cada círculo por separado, y la suma de los números en dos círculos adyacentes debe ser primo.
Nota: el número del primer círculo siempre debe ser 1.
Inserte la descripción de la imagen aquí

Entrada

n (0 <n <20).

Salida

El formato de salida se muestra como ejemplo a continuación. Cada fila representa una serie de números circulares en el anillo que comienzan desde 1 en sentido horario y antihorario. El orden de los números debe cumplir los requisitos anteriores. Soluciones de impresión en orden lexicográfico.
Debe escribir un programa que complete el proceso anterior.
Imprima una línea en blanco después de cada caso.

Entrada de muestra

6
8

Salida de muestra

Caso 1:
1 4 3 2 5 6
1 6 5 2 3 4
Caso 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2

Traducción

El anillo consta de n círculos, como se muestra en la figura. Coloque los números naturales 1, 2, ..., n en cada círculo respectivamente, y la suma de los números en dos círculos adyacentes deben ser números primos.
Nota: El número del primer círculo siempre debe ser 1.
El formato de salida se muestra a continuación. Cada fila representa una serie de números circulares que comienzan en el sentido de las agujas del reloj y el 1 en el sentido contrario a las agujas del reloj en el anillo. La secuencia de números debe cumplir con los requisitos anteriores. Soluciones de impresión en orden lexicográfico.
Escribirás un programa para completar el proceso anterior.
En cada caso, se imprime una línea en blanco.

Tres, la pregunta se desmonta

El tema esta vez es muy conciso y claro.

Coloque los números naturales 1, 2, ..., n en cada círculo respectivamente, y la suma de los números en dos círculos adyacentes deben ser números primos.
Nota: El inicio del círculo siempre debe ser 1.

Esta oración nos dice tres piezas de información:

  1. Los números del 1 al n deben organizarse en un anillo conectado de extremo a extremo, es decir, el primer número y el último número están conectados.
  2. La suma de dos números adyacentes debe ser un número primo.
  3. Todos los números de salida deben comenzar con 1.

Bien, entonces comenzaremos a resolver el problema directamente.

Cuatro, ideas para resolver problemas

En primer lugar, la pregunta requiere que la suma de dos números adyacentes sea un número primo, y debe combinarse en un anillo y usar todos los números.
Entonces, ¿cuál fue nuestra primera reacción? Coloque los números después del 1 en la cola uno por uno para ver si puede formar un número primo con el número anterior. Si puede, actualice la serie, si no, cambie al siguiente número y colóquelo. Después de actualizar la secuencia, vuelva a rellenar la secuencia desde el principio hasta que la longitud de la secuencia sea igual an o no se puedan insertar algunos números.
Veamos un ejemplo.
Por ejemplo, ingresamos

6

En este momento, primero inicializamos la cola y la cola es

1

Entonces veamos si 2 se puede empaquetar detrás de 1, 1 + 2 = 3 es un número primo, puede conectarlo, actualizar la cola

1 2

Luego vea si se puede insertar 3, 2 + 3 = 5 es un número primo, insértelo, actualice la cola

1 2 3

Luego vea si se puede insertar 4, 3 + 4 = 7 es un número primo, insértelo, actualice la cola

1 2 3 4

Y así sucesivamente, 5 + 4 = 9 no es un número primo, para ver el siguiente
64 = 10 no es primo +, pero en este momento no hay ningún número siguiente que se pueda rellenar, demuestre que este tipo no funciona, luego caemos de nuevo en un digital
esto Cuando la cola vuelve a

1 2 3

Debido a que 4 llevaría a que las columnas subsiguientes no pueden ser perfectas, continuaremos mirando un número
35 = 8 no es primo +, el siguiente
3 + 6 = 9 no es un número primo, pero luego no lo resolvieron, seguimos volviendo a una cola
esto Cuando la cola vuelve a

1 2

Luego repita este comportamiento, podemos encontrar la primera cola que cumpla con el significado de la pregunta

1 4 3 2 5 6

Luego lo mostramos y continuamos buscando el siguiente.
Esta es la idea específica de esta pregunta. Entonces, ¿cómo lograrlo?
Debido a que es posible que tengamos que volver a la cola del paso anterior, la forma en que guardamos la cola del paso anterior es muy importante. Aquellos que han estudiado estructuras de datos deben saber que existe tal concepto en C ++ - stack. Esto es exactamente lo que necesitamos salvar.
Entonces usamos la pila para guardar, entonces, ¿qué método es usar la pila en la estructura de datos?
Sí, es recursividad, por lo que usamos la recursividad para escribir esta pregunta.
Después de resolver el problema de almacenamiento, el siguiente paso es juzgar el problema.
Debido a que necesitamos juzgar un número primo cada vez que sumamos y restamos, será mejor que escribamos el número primo de juicio como una función para que podamos llamar.
Sin embargo, llamar a la función también llevará mucho tiempo de cálculo, por lo que podemos marcar los números primos por adelantado, es decir, hacer una tabla de números primos.
Creamos una matriz, porque el título máximo n es 20, por lo que podemos crear una matriz de 41, inicializarla en 0 y luego marcar el número no primo como 1. Tendré comentarios detallados en el código para la tabla específica .
Después de resolver estos grandes problemas, el siguiente paso es prestar atención a los detalles del problema.
En primer lugar: el tema es una entrada de datos múltiples, y cada entrada de datos necesita la etiqueta de orden correspondiente. Por
ejemplo, el primer conjunto de datos que queremos generar

Caso 1:

El segundo punto al que se debe prestar atención es que cada vez que los datos encuentran todas las colas factibles, se debe generar una línea en blanco.
El tercer punto es también un punto que siempre he ignorado. Después de que se genera cada columna de datos, no debe haber espacios adicionales.
Lo anterior es la solución específica y los puntos principales de este problema.

Cinco, código de referencia

//
// Created by Verber.
//
#include "iostream"
#include "bits/stdc++.h"
#include "queue"
using namespace std;
int n;
int biao[42],zu[22],pd[22];//三个数组分别储存的是素数表,数列,以及判断该数字是否入队
void sushudabiao()//打表函数
{
    
    
    memset(biao,0,sizeof(biao));//初始化数组
    for (int i = 2; i<= 42; i++)
    {
    
    
        if(biao[i]==0)//如果是素数,它的倍数一定不是素数
        {
    
    
            for(int t=i*2;t<=42;t+=i)
            {
    
    
                biao[t]=1;
            }
        }
    }

}
void zhaohuan(int num)//递归函数
{
    
    
    if (num == n && biao[zu[0] + zu[n - 1]]==0)//当递归层数等于n时并且首尾数相加是素数的情况下跳出递归,输出数列
    {
    
    
        for (int i = 0; i <n-1; i++)
        {
    
    
            cout<<zu[i]<<" ";
        }
        cout<<zu[n-1]<<endl;//最后一个数字后面不能有多余的空格
        return;
    }
    else
    {
    
    
        for (int j = 2; j <= n; j++)//循环去寻找下一个塞进去数列的数字
        {
    
    
            if (!pd[j] && biao[j + zu[num - 1]]==0)
            {
    
    
                zu[num] = j;//把该数字入列
                pd[j] = 1;//表示该数字已入列
                zhaohuan(num + 1);//如果该数字能塞到当前数列后面,重新查找下一个数字
                pd[j] = 0;//当执行完上一步的递归后,无论能否成数列,都要让该数字出列,查找新的能塞到当前位置的数字,找新的数列。
            }
        }
    }
}
int main()
{
    
    
    sushudabiao();
    int i=1;
    while (scanf("%d",&n)!=EOF) {
    
    
        cout<<"Case "<<i++<<":"<<endl;
        zu[0] = 1;
        memset(pd,0,sizeof(pd));//每一步初始化判断列表。可省略
        zhaohuan(1);
        cout<<endl;

    }
}

Supongo que te gusta

Origin blog.csdn.net/Verber/article/details/113101714
Recomendado
Clasificación