Cho một mảng arr[] chứa các số dương. Mục tiêu là tìm các tập con của các phần tử của arr[] sao cho trung vị của các giá trị của tập con cũng có mặt trong tập con đó.
Ví dụ
Đầu vào
arr[] = { 1,2,3 }
Đầu ra
Số tập con có trung vị cũng nằm trong tập con là: 4
Giải thích
Các tập có trung vị trong tập đó là: [1], trung vị là 1; [2], trung vị là 2; [3], trung vị là 3; [1,2,3], trung vị là 2
Đầu vào
arr[] = { 4,6,5 }
Đầu ra
Số tập con có trung vị cũng nằm trong tập con là: 4
Giải thích
Các tập có trung vị trong tập đó là: [4], [6], [5], [4,6,5]
Phương pháp sử dụng
Trong phương pháp này, chúng ta sẽ kiểm tra cho số phần tử chẵn và lẻ. Sau đó có thể tìm trung vị dựa trên thực tế rằng đối với số lượng phần tử lẻ, trung vị có mặt trong cùng tập con như phần tử giữa. Vì vậy chúng ta sẽ thêm 2^n - 1 vào biến đếm. Đối với tập con độ dài chẵn, chúng ta sẽ kiểm tra xem có hai phần tử giống nhau không, vì vậy đếm cho các tập con độ dài chẵn có hai phần tử giữa.
- Nhận mảng
arr[]các số dương. - Hàm
median_subset(arr, size)nhậnarrvà trả về số lượng tập con có trung vị cũng nằm trong tập con đó. - Hàm
check(int temp)nhận một số nguyên và trả về giai thừa của số đó bằng vòng lặp for từi=2đếni<=temp. - Tính
count = count * i, và trả về nó ở cuối vòng lặp làm giai thừa. - Hàm
com(int n, int r)nhậnnvàrvà trả về giá trị tổ hợpnCr. Bên trong lấytemp = check(r) * check(n - r)vàtemp_2 = check(n) / temp. Trả vềtemp_2là giá trị tính được. - Hàm
power(int n, int r)nhậnnvàrvà trả về giá trịn^r. - Nếu
rlà 0 thì đáp án sẽ là 1 nên trả về 1. - Lấy
total = power(n, r / 2)(n^(r/2)). - Cập nhật
totalvớitotal^2 % mod. Trong đómod=1000000007. - Nếu
rlà chẵn thì trả vềtemplà(total * n) % mod, ngược lại trả vềtotal. - Bên trong hàm
median_subset(), lấycount = power(2, size - 1)là số tập con độ dài lẻ. - Sắp xếp mảng
arr[]bằngsort(arr, arr + size). - Sử dụng vòng lặp while, chúng ta sẽ kiểm tra cho mỗi phần tử phần tử giữa bên trái cho đến khi chúng bằng nhau.
- Lấy
temp_2 = size - 1 - templà số phần tử bên phải của phần tử giữa bên phải. - Lấy
temp_3 = ilà số phần tử bên trái của phần tử giữa bên trái. - Thêm các tập con độ dài chẵn được chọn vào biến đếm:
count = (count + com(temp_3 + temp_2, temp_3)) % mod. - Cuối cùng của vòng lặp while, chúng ta sẽ có biến đếm.
- Trả về biến đếm làm kết quả.
Ví dụ mã
#include <algorithm>
#include <iostream>
using namespace std;
#define mod 1000000007
int check(int temp) {
int count = 1;
for (int i = 2; i <= temp; i++) {
count = count * i;
}
return count;
}
int com(int n, int r) {
int temp = check(r) * check(n - r);
int temp_2 = check(n) / temp;
return temp_2;
}
int power(int n, int r) {
if (r == 0) {
return 1;
}
int total = power(n, r / 2);
total = (total * total) % mod;
if (r % 2) {
int temp = (total * n) % mod;
return temp;
} else {
return total;
}
}
int median_subset(int* arr, int size) {
int count = power(2, size - 1);
sort(arr, arr + size);
for (int i = 0; i < size; ++i) {
int temp = i + 1;
while (temp < size && arr[temp] == arr[i]) {
int temp_2 = size - 1 - temp;
int temp_3 = i;
count = (count + com(temp_3 + temp_2, temp_3)) % mod;
temp++;
}
}
return count;
}
int main() {
int arr[] = { 4, 5, 4, 6 };
int size = sizeof(arr) / sizeof(arr[0]);
cout << "Số tập con có trung vị cũng nằm trong tập con là: " << median_subset(arr, size);
return 0;
}
Đầu ra
Nếu chạy mã trên, sẽ tạo ra đầu ra sau:
Số tập con có trung vị cũng nằm trong tập con là: 9