计算C ++中GCD等于给定数的集合的子集数
给定一个包含正数的数组ar和一个包含gcd的数组GCD[]values.The目标是找到具有GCD[]中给定的gcd值的arr[]元素子集的数量。
例如
输入值
arr[] = {10, 5, 6, 3}, GCD[] = {2, 3, 5}输出结果
GCD等于给定数的集合的子集数计数为: 1 2 2
说明
The subsets with GCD equal to 2 is [ 10, 6 ]. Subsets with GCD equal to 3 is [ 3 ], [ 6,3 ] Subsets with GCD equal to 5 is [ 5 ], [ 10, 5 ]
输入值
arr[] = {10, 21, 7, 8}, GCD[] = {2, 7, 5}输出结果
GCD等于给定数的集合的子集数计数为: 1 2 0
说明
The subsets with GCD equal to 2 is [ 10, 8 ]. Subsets with GCD equal to 7 is [ 7 ], [ 21,7 ] There are no subsets with GCD equal to 5.
以下程序中使用的方法如下-
在这种方法中,我们将创建一个unordered_map<int,int>um_1来存储arr[]元素的频率,并创建一个相似的图um_2来存储给定gcd的子集数量。以arr[]中元素的最大值作为计数。现在运行一个从i=count到i>=1的循环,找到当前gcd的子集数。为此,我们将计算um_1中i的倍数。如果i的倍数总数为g,那么具有gcdi的子集的总数为2-1temp。其中temp是gcd大于i但不等于i的子集的数量。
将两个数组用于arr[]和GCD[]。
函数subset_GCD(intarr[],intsize_arr,intGCD[],intsize_GCD)接受两个数组及其长度,并返回GCD等于给定数的集合的子集数的计数。
函数subset_GCD(intarr[],intsize_arr,intGCD[],intsize_GCD)接受两个数组及其长度,并返回GCD等于给定数的集合的子集数的计数。
将初始计数设为0。
使用for循环遍历arr[]并找到更新计数作为最大值,并使用um_1[arr[i]]++用频率更新um_1。
使用从i=count到i>=1的for循环,将总数作为i的倍数和temp=0的频率之和作为gcd大于i但不等于i的子集数。
再次从j=2遍历到j*i<=count,将um_1[j*i]添加到总计,并将um_2[j*i]添加到temp。
在两个for循环结束后,设置um_2[i]=(1<<total)−1−temp。
打印um_2[GCD[i]]以得到具有给定GCD子集数的结果数组。
示例
#include<bits/stdc++.h> using namespace std; void subset_GCD(int arr[], int size_arr, int GCD[], int size_GCD){ unordered_map<int, int> um_1, um_2; int count = 0; for (int i=0; i<size_arr; i++){ count = max(count, arr[i]); um_1[arr[i]]++; } for (int i = count; i >=1; i−−){ int temp = 0; int total = um_1[i]; for (int j = 2; j*i <= count; j++){ total += um_1[j*i]; temp += um_2[j*i]; } um_2[i] = (1<<total) − 1 − temp; } cout<<"GCD等于给定数的集合的子集数计数为: "; for (int i=0; i<size_GCD ; i++){ cout<<um_2[GCD[i]]<<" "; } } int main(){ int GCD[] = {2, 3}; int arr[] = {9, 6, 2}; int size_arr = sizeof(arr)/sizeof(arr[0]); int size_GCD = sizeof(GCD)/sizeof(GCD[0]); subset_GCD(arr, size_arr, GCD, size_GCD); return 0; }输出结果
如果我们运行上面的代码,它将生成以下输出-
GCD等于给定数的集合的子集数计数为: 2 1