Cho một mảng arr chứa các số dương và một mảng GCD[] chứa các giá trị gcd. Mục tiêu là tìm số lượng tập con của các phần tử của arr[] có giá trị gcd như cho trong GCD[].
Ví dụ
Đầu vào
arr[] = {10, 5, 6, 3}, GCD[] = {2, 3, 5}
Đầu ra
Số tập con có GCD bằng số cho trước là: 1 2 2
Giải thích
Các tập con với GCD bằng 2 là [10, 6]. Tập con với GCD bằng 3 là [3], [6,3]. Tập con với GCD bằng 5 là [5], [10, 5]
Đầu vào
arr[] = {10, 21, 7, 8}, GCD[] = {2, 7, 5}
Đầu ra
Số tập con có GCD bằng số cho trước là: 1 2 0
Giải thích
Các tập con với GCD bằng 2 là [10, 8]. Tập con với GCD bằng 7 là [7], [21,7]. Không có tập con nào với GCD bằng 5.
Phương pháp sử dụng
Trong phương pháp này, chúng ta sẽ tạo một unordered_map<int, int> um_1 để lưu tần suất các phần tử của arr[] và bản đồ tương tự um_2 để lưu số lượng tập con với gcd cho trước. Lấy giá trị lớn nhất trong các phần tử của arr[] làm count. Bây giờ chạy vòng lặp từ i=count đến i>=1 và tìm số lượng tập con cho gcd hiện tại. Để làm điều này, chúng ta sẽ đếm số bội số của i trong um_1. Nếu số bội số của i là total thì số tập con với gcd i là 2^total - 1 - temp. Trong đó temp là số tập con có gcd lớn hơn i nhưng không bằng i.
- Nhận hai mảng cho
arr[]vàGCD[]. - Hàm
subset_GCD(int arr[], int size_arr, int GCD[], int size_GCD)nhận cả hai mảng và độ dài của chúng và trả về số lượng tập con của tập hợp có GCD bằng số cho trước. - Khởi tạo biến đếm ban đầu là 0.
- Duyệt
arr[]bằng vòng lặp for, tìm và cập nhậtcountlà giá trị tối đa và cập nhậtum_1với tần suất bằngum_1[arr[i]]++. - Sử dụng vòng lặp for từ
i=countđếni>=1, lấytotallà tổng tần suất của các bội số củaivàtemp=0là số tập con có gcd lớn hơninhưng không bằngi. - Duyệt lại từ
j=2đếnj*i <= count, cộngum_1[j*i]vàototalvà cộngum_2[j*i]vàotemp. - Sau khi kết thúc cả hai vòng lặp for, đặt
um_2[i] = (1<<total) - 1 - temp. - In
um_2[GCD[i]]cho mảng kết quả có số lượng tập con với GCD cho trước.
Ví dụ mã
#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 << "Số tập con có GCD bằng số cho trước là: ";
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;
}
Đầu ra
Nếu chạy mã trên, sẽ tạo ra đầu ra sau:
Số tập con có GCD bằng số cho trước là: 2 1