根据素数的最高幂对给定的数组进行降序排序
给定一个大小为N的数组arr[] 。任务是根据最高表达程度对arr[]中的元素进行降序排序。一个数的最高度定义为它可以表示为它的因子的幂的最大值。
笔记:
- 如果数字具有相同的表达程度,则原始数组中最先出现的元素将在排序后的数组中最先出现。
- 如果两个数字的最高度数相同,则应使用先到先服务的方法。
例子:
Input: arr[] = {81, 25, 27, 32, 51}
Output: [32, 81, 27, 25, 51]
Explanation: After prime factorization
81 can be represented as 811, 92, or 34. For the highest degree of expression, choose (3)4 because 4 is greater than 2 and 1.
25 can be represented as 52.
27 can be represented as 33.
32 can be represented as 25.
51 can be represented as 511.
Now, sort them in descending order based on their power.
Therefore, 32 comes first since 25 has the highest power, followed by 81, 27, 25, and finally 51 with a power of 1.
Input: arr[] = {23, 6}
Output: [23, 6]
Explanation: Since 23 and 6 both have the same power(1), we print 23 which comes first, followed by 6.
方法:这个问题可以通过使用素数分解来解决。请按照以下步骤解决给定的问题。
- 一个数的最大幂可以通过将其分解为其质因数的乘积来获得。
- 在这些因素中选择具有最高功效的因素。
- 将数字的最高幂与该数字一起存储在一对中,并根据其因子的最高幂对该对进行排序。
- 使用 Eratosthenes 筛法预先计算10^5 以内的所有素数。
- 对于数组中的每个数字,找到该数字的所有因子,并将其因子的最高幂与该数字一起存储在一对整数的向量中。
- 根据第二个元素(表达式的最高顺序)按降序对该对进行排序。
下面是上述方法的实现。
C++
// C++ code to implement the above approach
#include
#include
using namespace std;
bitset<500001> Primes;
vector Factors;
// Function to compute Sieve of Eratosthenes
void SieveOfEratosthenes(int n)
{
Primes[0] = 1;
for (int i = 3; i <= n; i += 2) {
if (Primes[i / 2] == 0) {
for (int j = 3 * i; j <= n; j += 2 * i)
Primes[j / 2] = 1;
}
}
for (int i = 2; i <= 500001; i++) {
if (!Primes[i])
Factors.push_back(i);
}
}
// Compare function for sorting
bool compare(const pair& a,
const pair& b)
{
return a.second > b.second;
}
// Function to find any log(a) base b
int log_a_to_base_b(int a, int b)
{
return log(a) / log(b);
}
// Function to find the Highest Power
// of K which divides N
int HighestPower(int N, int K)
{
int start = 0, end = log_a_to_base_b(N, K);
int ans = 0;
while (start <= end) {
int mid = start + (end - start) / 2;
int temp = (int)(pow(K, mid));
if (N % temp == 0) {
ans = mid;
start = mid + 1;
}
else {
end = mid - 1;
}
}
return ans;
}
// Function to display N numbers
// on the basis of their Highest Order
// of Expression in descending order
void displayHighestOrder(int arr[], int N)
{
vector > Nums;
for (int i = 0; i < N; i++) {
// The least power of a number
// will always be 1 because
// that number raised to
// the power 1 is it itself
int temp = 1;
for (auto& Prime : Factors) {
// The factor of a number greater than
// its square root is the number itself
// which is considered in temp
if (Prime * Prime > arr[i])
break;
else if (arr[i] % Prime == 0)
temp = max(
temp,
HighestPower(arr[i], Prime));
}
Nums.push_back(make_pair(arr[i], temp));
}
sort(Nums.begin(), Nums.end(), compare);
for (int i = 0; i < N; i++) {
cout << Nums[i].first << " ";
}
cout << endl;
}
// Driver Code
int main()
{
SieveOfEratosthenes(500000);
int arr[] = { 81, 25, 27, 32, 51 };
int N = sizeof(arr) / sizeof(arr[0]);
// Function Call
displayHighestOrder(arr, N);
return 0;
}
Python3
# Python code for the above approach
import math as Math
Primes = [0] * 500001
Factors = []
# Function to compute Sieve of Eratosthenes
def SieveOfEratosthenes(n):
Primes[0] = 1
for i in range(3, n + 1, 2):
if (Primes[i // 2] == 0):
for j in range(3 * i, n + 1, 2 * i):
Primes[j // 2] = 1
for i in range(2, 500001) :
if (not Primes[i]):
Factors.append(i)
# Compare function for sorting
def compare(a, b):
return b.second - a.second
# Function to find any log(a) base b
def log_a_to_base_b(a, b):
return Math.log(a) / Math.log(b)
# Function to find the Highest Power
# of K which divides N
def HighestPower(N, K):
start = 0
end = log_a_to_base_b(N, K)
ans = 0
while (start <= end):
mid = start + Math.floor((end - start) / 2)
temp = (Math.pow(K, mid))
if (N % temp == 0):
ans = mid
start = mid + 1
else:
end = mid - 1
return ans
# Function to display N numbers
# on the basis of their Highest Order
# of Expression in descending order
def displayHighestOrder(arr, N):
Nums = []
for i in range(N):
# The least power of a number
# will always be 1 because
# that number raised to
# the power 1 is it itself
temp = 1
for Prime in Factors:
# The factor of a number greater than
# its square root is the number itself
# which is considered in temp
if (Prime * Prime > arr[i]):
break
elif (arr[i] % Prime == 0):
temp = max( temp, HighestPower(arr[i], Prime))
Nums.append({"first": arr[i], "second": temp})
Nums = sorted(Nums, key=lambda l: l["second"], reverse=True)
for i in range(N):
print(Nums[i]["first"], end= " ")
print('')
# Driver Code
SieveOfEratosthenes(500000)
arr = [81, 25, 27, 32, 51]
N = len(arr)
# Function Call
displayHighestOrder(arr, N)
# This code is contributed by gfgking.
Javascript
32 81 27 25 51
时间复杂度: O(N 1.5 *log(K)),其中 K 是数组中的最大元素。
辅助空间: O(1)