[Ejercicio auxiliar 3 para algoritmos de aprendizaje] Universidad de Pekín POJ2956: Números repetidos

lista de temas

1. Enumeración: 1753, 2965

2. Codicioso: 2109, 2586

3. Árbol de expansión mínimo: 2485, 1258

4. Clasificación: 2388

5. Búsqueda de optimización en profundidad: 1321, 2251

6. Búsqueda optimizada de amplitud: 3278, 1426

7. Técnicas de búsqueda simple y poda: 2676

8. El problema de la mochila: 1837

9. Clasificación topológica: 1094

10. Algoritmo de ruta más corta: 1062, 1125, 2240

11. Árbol de Huffman: 3253

12. Métodos de búsqueda eficientes como tabla hash y búsqueda binaria: 2151, 2503
 

Continúe practicando la enumeración esta semana.

Universidad de Pekín POJ2956: Números repetidos

tema

Portal

analizar

Entrada : el archivo de prueba de entrada contendrá varios casos de prueba, cada caso de prueba constará de una sola línea que contiene el número entero  n  , donde 1 ≤  n  ≤ 1000000. El final del archivo está marcado por  un caso de prueba con n  = 0 y no debe procesarse.

Salida : para cada caso de entrada, el programa debe imprimir el n-ésimo  número único en una línea  .

Ejemplo de entrada:

25

10000

0

Salida de ejemplo:

27

26057

Mi línea de pensamiento:

Es una solución violenta, enumeración + clasificación para juzgar si se cumplen las condiciones.

 

Avanzado

1. Utilice BFS :

No esperaba usar BFS en absoluto.

——El estado inicial es 1~9, y el estado de la siguiente capa se puede obtener agregando continuamente 0~9 después del estado inicial, y el estado de la segunda capa se expande continuamente hasta que la expansión alcanza el estado 1000000. Cada estado contiene dos atributos value y digit, value es el valor del estado, asumiendo que es 134, entonces digit es 11010, d[i]=1 significa que i está en el valor, cuando el número 0~9 se agrega después el número 134 (Suponga que el número agregado es 1), cómo juzgar si 1 ha aparecido en 134, valor = 1, luego dígito = 10, y la operación de 11010 y 10 es 11010 y 10, si el resultado no es igual a 0, significa que 1 está en 134 existe, de lo contrario no existe.

2. Considere algunos casos para reducir la enumeración :

Cree una matriz, guarde cada bit y juzgue si hay números repetidos (aquí se parece un poco al almacenamiento de bits mencionado en el Capítulo 1). Por ejemplo, para un número 128267, su segundo dígito (contando de derecha a izquierda) es el mismo que el cuarto dígito, entonces el número en forma de 1282** no necesita enumerarse y puede enumerarse directamente desde 128300. Esto acelera el tiempo de enumeración.

el código 

1. Utilice BFS:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int N = 1000000;
 7 struct Number
 8 {
 9     int value;  //数字的十进制表示
10     int digit;  //二进制序列,从右往左数digit[i]==1表示value中有i
11 
12     Number(){}
13     Number(int v, int d):value(v), digit(d){}
14 }ans[N+10];
15 
16 int main()
17 {
18     for(int i=1; i<10; i++)
19         ans[i] = Number(i, 1<<i);
20 
21     int k = 1;
22     for(int cur=10; cur<=N; k++)
23     {
24         int v = ans[k].value;
25         int d = ans[k].digit;
26 
27         for(int i=0; i<10; i++)
28         {
29             if( !(d & (1<<i)))
30                 ans[cur++] = Number(v*10+i, d|1<<i);
31         }
32     }
33 
34     int n;
35     while(scanf("%d", &n)==1 && n)
36         printf("%d\n", ans[n].value);
37     return 0;
38 }

2. Reducir la enumeración:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 const int N = 1000000;
 7 int ans[N+1] = {0};
 8 int power[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
 9 
10 void init()
11 {
12     int d[10];  //存储数字x
13     int v[10];  //v[i]表示数字i是否在x中出现过
14     int cur = 1;
15     int x, y=1;
16     while(cur<=N)
17     {
18         x = y;
19         memset(v, -1, sizeof(v));
20         memset(d, 0, sizeof(d));
21 
22         int i, j;
23         for(i=0; x!=0; i++)
24         {
25             d[i] = x % 10;
26             if(v[d[i]]!=-1)
27                 break;
28             v[d[i]] = i;
29             x /= 10;
30         }
31         if(!x)
32         {
33             ans[cur++] = y;
34             y++;
35         }
36         else
37         {
38             j = v[d[i]];
39             for(i--; i>=j; i--)
40                 x = x*10+d[i];
41             x++;
42             y = x*power[j];
43         }
44     }
45 }
46 
47 int main()
48 {
49     init();
50     int n;
51     while(cin>>n && n)
52         cout<<ans[n]<<endl;
53     return 0;
54 }

Supongo que te gusta

Origin blog.csdn.net/weixin_43594181/article/details/123248149
Recomendado
Clasificación