Los números súper feos son números positivos cuyos factores primos están todos en la lista de primos dada. Dado un número n, la tarea es encontrar el n-ésimo número súper feo.
Se puede suponer que un conjunto dado de números primos está ordenado. Además, el primer número Super Ugly es 1 por convención.
Ejemplos:
Input : primes[] = [2, 5] n = 5 Output : 8 Super Ugly numbers with given prime factors are 1, 2, 4, 5, 8, ... Fifth Super Ugly number is 8 Input : primes[] = [2, 3, 5] n = 50 Output : 243 Input : primes[] = [3, 5, 7, 11, 13] n = 9 Output: 21
En nuestra publicación anterior, discutimos el número feo . Este problema es básicamente una extensión de Ugly Numbers .
Una solución simple para este problema es elegir uno por uno cada número comenzando desde 1 y encontrar todos sus factores primos, si todos los factores primos se encuentran en el conjunto dado de primos, eso significa que el número es súper feo. Repite este proceso hasta que obtengamos el enésimo Número Súper Feo.
Una solución eficiente para este problema es similar al Método-2 de Ugly Number . Aquí está el algoritmo:
- Sea k el tamaño de una array dada de números primos.
- Declara un conjunto para números súper feos.
- Inserta el primer número feo (que siempre es 1) en el conjunto.
- Inicialice la array multiple_of[k] de tamaño k con 0. Cada elemento de esta array es un iterador para el primo correspondiente en la array primos[k].
- Inicialice la array nextMultipe[k] con primos[k]. Esta array se comporta como las siguientes variables múltiples de cada número primo en una array dada de primos[k], es decir; nextMultiple[i] = primos[i] * feo[++multiple_of[i]].
- Ahora repite hasta que haya n elementos en el conjunto feo.
a). Encuentre el mínimo entre los múltiplos actuales de números primos en la array nextMultiple[] e insértelo en el conjunto de números feos.
b). Luego encuentra que este mínimo actual es múltiplo de cuál primo.
C). Aumentar el iterador en 1, es decir; ++multiple_Of[i], para el próximo múltiplo del número primo actual seleccionado y actualice nextMultiple para él.
A continuación se muestra la implementación de los pasos anteriores.
CPP
// C++ program to find n'th Super Ugly number #include<bits/stdc++.h> using namespace std; // Function to get the nth super ugly number // primes[] --> given list of primes f size k // ugly --> set which holds all super ugly // numbers from 1 to n // k --> Size of prime[] int superUgly(int n, int primes[], int k) { // nextMultiple holds multiples of given primes vector<int> nextMultiple(primes, primes+k); // To store iterators of all primes int multiple_Of[k]; memset(multiple_Of, 0, sizeof(multiple_Of)); // Create a set to store super ugly numbers and // store first Super ugly number set<int> ugly; ugly.insert(1); // loop until there are total n Super ugly numbers // in set while (ugly.size() != n) { // Find minimum element among all current // multiples of given prime int next_ugly_no = *min_element(nextMultiple.begin(), nextMultiple.end()); // insert this super ugly number in set ugly.insert(next_ugly_no); // loop to find current minimum is multiple // of which prime for (int j=0; j<k; j++) { if (next_ugly_no == nextMultiple[j]) { // increase iterator by one for next multiple // of current prime multiple_Of[j]++; // this loop is similar to find dp[++index[j]] // it --> dp[++index[j]] set<int>::iterator it = ugly.begin(); for (int i=1; i<=multiple_Of[j]; i++) it++; nextMultiple[j] = primes[j] * (*it); break; } } } // n'th super ugly number set<int>::iterator it = ugly.end(); it--; return *it; } /* Driver program to test above functions */ int main() { int primes[] = {2, 5}; int k = sizeof(primes)/sizeof(primes[0]); int n = 5; cout << superUgly(n, primes, k); return 0; }
Producción:
8
Este artículo es una contribución de Shashank Mishra (Gullu) . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Otro método (usando la cola de prioridad)
Aquí usamos la cola de prioridad mínima del montón.
La idea es empujar el primer feo no. que es 1 en la cola de prioridad y en cada iteración toma la parte superior de la cola de prioridad y empuja todos los múltiplos de esa parte superior en la cola de prioridad.
Suponiendo que a[] = {2, 3, 5},
por lo que en la primera iteración 1 es superior, por lo que se extrae 1 y se presiona 1 * 2, 1 * 3, 1 * 5.
En la segunda iteración, el mínimo es 2, por lo que se extrae y se presiona 2 * 2, 2 * 3, 2 * 5 y así sucesivamente.
Implementación:
CPP
// C++ program for super ugly number #include<bits/stdc++.h> using namespace std; // function will return the nth super ugly number int ugly(int a[], int size, int n){ // n cannot be negative hence // return -1 if n is 0 or -ve if(n <= 0) return -1; if(n == 1) return 1; // Declare a min heap priority queue priority_queue<int, vector<int>, greater<int>> pq; // Push all the array elements to priority queue for(int i = 0; i < size; i++){ pq.push(a[i]); } // once count = n we return no int count = 1, no; while(count < n){ // Get the minimum value from priority_queue no = pq.top(); pq.pop(); // If top of pq is no then don't increment count. // This to avoid duplicate counting of same no. if(no != pq.top()) { count++; // Push all the multiples of no. to priority_queue for(int i = 0; i < size; i++){ pq.push(no * a[i]); // cnt+=1; } } } // Return nth super ugly number return no; } /* Driver program to test above functions */ int main(){ int a[3] = {2, 3,5}; int size = sizeof(a) / sizeof(a[0]); cout << ugly(a, size, 10)<<endl; return 0; }
Python3
# Python3 program for super ugly number # function will return the nth super ugly number def ugly(a, size, n): # n cannot be negative hence return -1 if n is 0 or -ve if(n <= 0): return -1 if(n == 1): return 1 # Declare a min heap priority queue pq = [] # Push all the array elements to priority queue for i in range(size): pq.append(a[i]) # once count = n we return no count = 1 no = 0 pq = sorted(pq) while(count < n): # sorted(pq) # Get the minimum value from priority_queue no = pq[0] del pq[0] # If top of pq is no then don't increment count. # This to avoid duplicate counting of same no. if(no != pq[0]): count += 1 # Push all the multiples of no. to priority_queue for i in range(size): pq.append(no * a[i]) # cnt+=1 pq = sorted(pq) # Return nth super ugly number return no # /* Driver program to test above functions */ if __name__ == '__main__': a = [2, 3,5] size = len(a) print(ugly(a, size, 1000)) # This code is contributed by mohit kumar 29.
Javascript
<script> // Javascript program for super ugly number //function will return the nth super ugly number function ugly(a,size,n) { //n cannot be negative hence return -1 if n is 0 or -ve if(n <= 0) return -1; if(n == 1) return 1; // Declare a min heap priority queue let pq=[];; // Push all the array elements to priority queue for(let i = 0; i < size; i++){ pq.push(a[i]); } // once count = n we return no let count = 1, no; pq.sort(function(a,b){return a-b;}) ; while(count < n){ // Get the minimum value from priority_queue no = pq.shift(); // If top of pq is no then don't increment count. This to avoid duplicate counting of same no. if(no != pq[0]) { count++; //Push all the multiples of no. to priority_queue for(let i = 0; i < size; i++){ pq.push(no * a[i]); // cnt+=1; } } pq.sort(function(a,b){return a-b;}) ; } // Return nth super ugly number return no; } /* Driver program to test above functions */ let a=[2, 3,5]; let size = a.length; document.write(ugly(a, size, 1000)); // This code is contributed by unknown2108 </script>
Producción:
51200000
Complejidad de tiempo: O(n*size*logn)
Espacio auxiliar: O(n)
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA