给定两个数组A[] ,由N 个整数和B[] ,由 M 种巧克力的口味值和一个整数X 组成,任务是根据条件找到可以收到巧克力的最大人数一个人只能拥有一种巧克力,其口味值在[A[i] – X, A[i] + X] 范围内。
注意:巧克力一旦送给一个人,就不能再送给任何其他人。
例子:
Input: A[] = {90, 49, 20, 39, 60}, B[] = {14, 24, 82}, X = 15
Output: 3
Explanation:
1st person can pick the 3rd chocolate as the value of the 3rd chocolate ( = 82 ) lies in the range [75 ( = 90 – 15 ), 105 ( = 90 + 15)].
2nd person can’t pick any chocolate because there is no chocolate with value in the range [34 ( = 49 – 15 ), 64 ( = 49 + 15).
3rd person can pick the 1st chocolate as the value of the 1st chocolate lies in the range [5 ( = 20 – 15), 35 ( = 20 – 15)].
4th person can pick the 2nd chocolate because value of the 2nd chocolate lies in the range [ 24 ( = 39 – 15) and 54 ( = 39 – 15)].
5th person can’t pick any chocolate because there is no chocolate with value in the range [45 ( = 60 – 15), 75 ( = 60 – 15)].
Therefore, the total number of people receiving a chocolate is 3, which is the maximum possible.
Input: A[] = {2, 4, 6, 40, 50}, B[] = {38, 36}, X=13
Output: 2
方法:这个问题可以使用贪心技术/a> 和搜索来解决。这里的关键观察是对于任何第i 个人,如果可能,分配具有该范围内的最小可能值的巧克力。否则,从结果中排除该人。请按照以下步骤操作:
- 按非递减顺序对给定数组A[]和B[] 进行排序。
- 初始化一个多重集以存储数组B[]的元素。
- 初始化一个变量count = 0 ,以存储收到巧克力的人数。
- 遍历数组 A[] 并使用二分搜索或 lower_bound()找到可以分配给每个第 i 个人的最小巧克力值。检查该值是否在[a i – X, a i + X]范围内。
- 如果发现为真,则增加count并从 multiset 中删除此巧克力的值。
- 完成以上步骤后,打印count的值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count the maximum number
// of persons receiving a chocolate
int countMaxPersons(int* A, int n, int* B,
int m, int x)
{
// Initialize count as 0
int count = 0;
// Sort the given arrays
sort(A, A + n);
sort(B, B + m);
// Initialize a multiset
multiset s;
// Insert B[] array values into
// the multiset
for (int i = 0; i < m; i++)
s.insert(B[i]);
// Traverse elements in array A[]
for (int i = 0; i < n; i++) {
int val = A[i] - x;
// Search for the lowest value in B[]
auto it = s.lower_bound(val);
// If found, increment count,
// and delete from set
if (it != s.end()
&& *it <= A[i] + x) {
count++;
s.erase(it);
}
}
// Return the number of people
return count;
}
// Driver Code
int main()
{
int A[] = { 90, 49, 20, 39, 49 };
int B[] = { 14, 24, 82 };
int X = 15;
int N = sizeof(A) / sizeof(A[0]);
int M = sizeof(B) / sizeof(B[0]);
// Function Call
cout << countMaxPersons(A, N, B, M, X);
}
Python3
# Python3 program for the above approach
from bisect import bisect_left
# Function to count the maximum number
# of persons receiving a chocolate
def countMaxPersons(A, n, B, m, x):
# Initialize count as 0
count = 0
# Sort the given arrays
A = sorted(A)
B = sorted(B)
# Initialize a multiset
s = []
# Insert B[] array values into
# the multiset
for i in range(m):
s.append(B[i])
# Traverse elements in array A[]
for i in range(n):
val = A[i] - x
# Search for the lowest value in B[]
it = bisect_left(s,val)
# If found, increment count,
# and delete from set
if (it != len(s) and it <= A[i] + x):
count += 1
del s[it]
# Return the number of people
return count
# Driver Code
if __name__ == '__main__':
A = [90, 49, 20, 39, 49]
B = [14, 24, 82]
X = 15
N = len(A)
M = len(B)
# Function Call
print(countMaxPersons(A, N, B, M, X))
# This code is contributed by mohit kumar 29
3
时间复杂度: O(N*log N)
辅助空间: O(M)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。