给定C个磁体和代表N个索引位置的数组arr [] ,其中C≤N 。任务是将这些磁铁放置在这些可用的索引处,以使两个最近的磁铁之间的距离尽可能大。
例子:
Input: C = 4, arr[] = {1, 2, 5, 8, 10, 18}
Output: 4
We can place 4 magnets to positions 1, 5, 10, 18 so maximum distance is minimum of ( dist(1, 5), dist(5, 10), dist(10, 18) ) = dist(1, 5) = 4.
And it will be the maximum possible distance between two nearest magnets.
Input: C = 3, arr[] = {5, 7, 11, 20, 23}
Output: 6
We can place 3 magnets to positions 5, 11, 23 so answer will be minimum of ( dist(5, 11), dist(11, 23) ) = dist(5, 11) = 6.
天真的方法:找到所有可能的C(n,c)种可能的磁体位置,并找到一种最大化两个磁体之间距离的磁体,其中C(n,c)从n个给定对象中选择c个对象。
高效方法:将mx设为最大可能距离,因此所有大于0且小于mx的x都将允许放置磁体,但是对于所有大于mx的y,将无法放置磁体。因此,我们可以使用二进制搜索来找到最大可能的距离。
由于我们的答案将始终位于0到给定N个索引中的最大索引之间。因此,应用二进制搜索并找到介于最低值和最高值之间的中间值,例如“ mid”,使该函数检查是否有可能以“ mid”为最大可能距离放置C磁体。
总时间复杂度将为O(nlog(n)),因为二进制搜索将使用O(log(n))和O(n)来检查是否可以放置所有C磁体。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to check if it is possible
// to place C magnets assuming mid as
// maximum possible distance
bool isPossible(int arr[], int n, int C, int mid)
{
// Variable magnet will store count of magnets
// that got placed and currPosition will store
// the position of last placed magnet
int magnet = 1, currPosition = arr[0];
for (int i = 1; i < n; i++) {
// If difference between current index and
// last placed index is greater than or equal to mid
// it will allow placing magnet to this index
if (arr[i] - currPosition >= mid) {
magnet++;
// Now this index will become
// last placed index
currPosition = arr[i];
// If count of magnets placed becomes C
if (magnet == C)
return true;
}
}
// If count of placed magnet is
// less than C then return false
return false;
}
// Function for modified binary search
int binarySearch(int n, int C, int arr[])
{
int lo, hi, mid, ans;
// Sort the indices in ascending order
sort(arr, arr + n);
// Minimum possible distance
lo = 0;
// Maximum possible distance
hi = arr[n - 1];
ans = 0;
// Run the loop until lo becomes
// greater than hi
while (lo <= hi) {
mid = (lo + hi) / 2;
// If not possibble, decrease value of hi
if (!isPossible(arr, n, C, mid))
hi = mid - 1;
else {
// Update the answer
ans = max(ans, mid);
lo = mid + 1;
}
}
// Return maximum possible distance
return ans;
}
// Driver code
int main()
{
int C = 4;
int arr[] = { 1, 2, 5, 8, 10, 18 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << binarySearch(n, C, arr) << endl;
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Function to check if it is possible
// to place C magnets assuming mid as
// maximum possible distance
static boolean isPossible(int []arr, int n,
int C, int mid)
{
// Variable magnet will store count of magnets
// that got placed and currPosition will store
// the position of last placed magnet
int magnet = 1, currPosition = arr[0];
for (int i = 1; i < n; i++)
{
// If difference between current index and
// last placed index is greater than or equal to mid
// it will allow placing magnet to this index
if (arr[i] - currPosition >= mid)
{
magnet++;
// Now this index will become
// last placed index
currPosition = arr[i];
// If count of magnets placed becomes C
if (magnet == C)
return true;
}
}
// If count of placed magnet is
// less than C then return false
return false;
}
// Function for modified binary search
static int binarySearch(int n, int C, int []arr)
{
int lo, hi, mid, ans;
// Sort the indices in ascending order
Arrays.sort(arr);
// Minimum possible distance
lo = 0;
// Maximum possible distance
hi = arr[n - 1];
ans = 0;
// Run the loop until lo becomes
// greater than hi
while (lo <= hi)
{
mid = (lo + hi) / 2;
// If not possibble, decrease value of hi
if (!isPossible(arr, n, C, mid))
hi = mid - 1;
else
{
// Update the answer
ans = Math.max(ans, mid);
lo = mid + 1;
}
}
// Return maximum possible distance
return ans;
}
// Driver code
public static void main(String args[])
{
int C = 4;
int []arr = { 1, 2, 5, 8, 10, 18 };
int n = arr.length;
System.out.println(binarySearch(n, C, arr));
}
}
// This code is contributed by Akanksha Rai
Python3
# Python 3 implementation of the approach
# Function to check if it is possible
# to place C magnets assuming mid as
# maximum possible distance
def isPossible(arr, n, C, mid):
# Variable magnet will store count of
# magnets that got placed and
# currPosition will store the position
# of last placed magnet
magnet = 1
currPosition = arr[0]
for i in range(1, n):
# If difference between current index
# and last placed index is greater than
# or equal to mid it will allow placing
# magnet to this index
if (arr[i] - currPosition >= mid):
magnet += 1
# Now this index will become
# last placed index
currPosition = arr[i]
# If count of magnets placed becomes C
if (magnet == C):
return True
# If count of placed magnet is
# less than C then return false
return False
# Function for modified binary search
def binarySearch(n, C, arr):
# Sort the indices in ascending order
arr.sort(reverse = False)
# Minimum possible distance
lo = 0
# Maximum possible distance
hi = arr[n - 1]
ans = 0
# Run the loop until lo becomes
# greater than hi
while (lo <= hi):
mid = int((lo + hi) / 2)
# If not possibble, decrease value of hi
if (isPossible(arr, n, C, mid) == False):
hi = mid - 1
else:
# Update the answer
ans = max(ans, mid)
lo = mid + 1
# Return maximum possible distance
return ans
# Driver code
if __name__ == '__main__':
C = 4
arr = [1, 2, 5, 8, 10, 18]
n = len(arr)
print(binarySearch(n, C, arr))
# This code is contributed by
# Surendra_Gangwar
C#
// C# implementation of the approach
using System;
class GFG
{
// Function to check if it is possible
// to place C magnets assuming mid as
// maximum possible distance
static bool isPossible(int []arr, int n,
int C, int mid)
{
// Variable magnet will store count of magnets
// that got placed and currPosition will store
// the position of last placed magnet
int magnet = 1, currPosition = arr[0];
for (int i = 1; i < n; i++)
{
// If difference between current index and
// last placed index is greater than or equal to mid
// it will allow placing magnet to this index
if (arr[i] - currPosition >= mid)
{
magnet++;
// Now this index will become
// last placed index
currPosition = arr[i];
// If count of magnets placed becomes C
if (magnet == C)
return true;
}
}
// If count of placed magnet is
// less than C then return false
return false;
}
// Function for modified binary search
static int binarySearch(int n, int C, int []arr)
{
int lo, hi, mid, ans;
// Sort the indices in ascending order
Array.Sort(arr);
// Minimum possible distance
lo = 0;
// Maximum possible distance
hi = arr[n - 1];
ans = 0;
// Run the loop until lo becomes
// greater than hi
while (lo <= hi)
{
mid = (lo + hi) / 2;
// If not possibble, decrease value of hi
if (!isPossible(arr, n, C, mid))
hi = mid - 1;
else
{
// Update the answer
ans = Math.Max(ans, mid);
lo = mid + 1;
}
}
// Return maximum possible distance
return ans;
}
// Driver code
static void Main()
{
int C = 4;
int []arr = { 1, 2, 5, 8, 10, 18 };
int n = arr.Length;
Console.WriteLine(binarySearch(n, C, arr));
}
}
// This code is contributed by chandan_jnu
PHP
= $mid)
{
$magnet++;
// Now this index will become
// last placed index
$currPosition = $arr[$i];
// If count of magnets placed becomes C
if ($magnet == $C)
return true;
}
}
// If count of placed magnet is
// less than C then return false
return false;
}
// Function for modified binary search
function binarySearch($n, $C, $arr)
{
// Sort the indices in ascending order
sort($arr, 0);
// Minimum possible distance
$lo = 0;
// Maximum possible distance
$hi = $arr[$n - 1];
$ans = 0;
// Run the loop until lo becomes
// greater than hi
while ($lo <= $hi)
{
$mid = ($lo + $hi) / 2;
// If not possibble, decrease value of hi
if (!isPossible($arr, $n, $C, $mid))
$hi = $mid - 1;
else
{
// Update the answer
$ans = max($ans, $mid);
$lo = $mid + 1;
}
}
// Return maximum possible distance
return $ans;
}
// Driver code
$C = 4;
$arr = array(1, 2, 5, 8, 10, 18);
$n = sizeof($arr);
echo binarySearch($n, $C, $arr) . "\n";
// This code is contributed
// by Akanksha Rai
?>
4
时间复杂度: O(n * log(n))