找到要从披萨上切下的最大一块,这样每个披萨至少有一块面积相同
给定一个数组arr[]表示圆形披萨的半径和一个整数N表示朋友的数量。任务是计算可以从比萨饼上切下的最大一块,这样每个朋友都可以得到一块面积相同的比萨饼。
不允许用一个以上的比萨做一片,每个朋友只能得到一份比萨。
例子:
Input: arr[] = {1, 1, 1, 2, 2, 3}, N = 6.
Output: 7.0686
Explanation: Take the area of the pizza with a radius of 3, and divide by 4. (Area 28.743 / 4 = 7.0686). Use a similarly sized piece from the remaining pizza of radius 2 because total area of pizza with radius 2 are > 7.0686
Input: arr[] = {6, 7}, N = 12
Output: 21.9911
方法:这个问题可以通过使用二分搜索来解决。请按照以下步骤解决给定的问题。
- 对数组进行排序,这将有助于对其使用二进制搜索。
- 现在,这个人可以拥有的最大面积是maxArea=π* a[n-1]*a[n-1] (圆的面积 - π*r 2 )。
- 设该人可以拥有的最小面积为minArea=0。
- 现在在这个给定的范围上应用二分搜索。
- 由于π是常数,因此应用从minArea=0到maxArea= a[n-1]*a[n-1] 的二进制搜索,然后在通过此二进制搜索得到( required radius * required radius )之后,将π乘以它。
- 由于二进制搜索中的中间值也可以是十进制的,因此对于一些迭代运行二进制搜索让我们说500 。
- 我们还需要为给定的二分搜索中间实现一个可能的函数。
- 如果该中间值对问题有效,则表示已计算出所需答案,并且需要转到二进制搜索的右侧以获得最大可能的答案。
- 如果该中间值对问题无效,则意味着该中间值右侧的所有答案也将无效,因此请转到左侧。
- 现在在isPossible()函数中,对于每个半径,检查有多少人可以从该披萨中获得碎片,如果获得披萨的总人数 >= 给定朋友,这意味着它是有效的,所以在二进制搜索中向右走,否则向左走。
- 打印通过上述操作找到的答案。
下面是上述方法的实现:
C++
#include
using namespace std;
// Function to check if current distribution
// is valid or not
bool isPossible(double x, int a[], int n, int k)
{
for (int i = n - 1; i >= 0; i--) {
int p = (a[i] * a[i]) / x;
k -= p;
if (k <= 0)
return true;
}
if (k <= 0)
return true;
return false;
}
// Function to solve given problem
long double maximumAreaPizza(int a[], int n, int k)
{
sort(a, a + n);
double l = 0, r = a[n - 1] * a[n - 1];
int count = 500;
double res = 0;
while (count--) {
double mid = double(l + r) / 2.0000;
if (isPossible(mid, a, n, k)) {
// cout << mid << " ";
res = mid;
l = mid;
}
else
r = mid;
}
// After calculating radius*radius for
// area multiply by pi(3.14) to get area
long double p1 = res * 3.14159265359;
return p1;
}
// Driver Code
int main()
{
// Number of pizza
int N = 6;
// Radius of all pizzas
int arr[] = { 1, 1, 1, 2, 2, 3 };
// Number of friends
int K = 6;
// Function Call
cout << maximumAreaPizza(arr, N, K);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG {
// Function to check if current distribution
// is valid or not
static boolean isPossible(double x, int []a, int n, int k)
{
for (int i = n - 1; i >= 0; i--) {
int p = (int)((a[i] * a[i]) / x);
k -= p;
if (k <= 0)
return true;
}
if (k <= 0)
return true;
return false;
}
// Function to solve given problem
static double maximumAreaPizza(int []a, int n, int k)
{
Arrays.sort(a);
double l = 0, r = a[n - 1] * a[n - 1];
int count = 500;
double res = 0;
while (count > 0) {
double mid = (double)(l + r) / 2.0000;
if (isPossible(mid, a, n, k)) {
// cout << mid << " ";
res = mid;
l = mid;
}
else
r = mid;
count--;
}
// After calculating radius*radius for
// area multiply by pi(3.14) to get area
double p1 = res * 3.14159265359;
return p1;
}
// Driver Code
public static void main(String args[])
{
// Number of pizza
int N = 6;
// Radius of all pizzas
int []arr = { 1, 1, 1, 2, 2, 3 };
// Number of friends
int K = 6;
// Function Call
System.out.println(maximumAreaPizza(arr, N, K));
}
}
// Thi code is contributed by code_hunt.
Python3
import math
# Function to solve the given problem
def maximumAreaPizza(radii, numberOfGuests):
areas = [math.pi * r * r for r in radii]
def isPossible(x):
k = 0
for a in areas:
k += a // x
if k >= numberOfGuests:
return True
return False
l, r = 0, max(areas)
while l + 1e-5 <= r:
x = (l + r) / 2
if isPossible(x):
l = x
else:
r = x
return round(x, 4)
# Driver Code
arr = [ 1, 1, 1, 2, 2, 3]
N = 6
print(maximumAreaPizza(arr, N))
C#
using System;
class GFG
{
// Function to check if current distribution
// is valid or not
static bool isPossible(double x, int []a, int n, int k)
{
for (int i = n - 1; i >= 0; i--) {
int p = (int)((a[i] * a[i]) / x);
k -= p;
if (k <= 0)
return true;
}
if (k <= 0)
return true;
return false;
}
// Function to solve given problem
static double maximumAreaPizza(int []a, int n, int k)
{
Array.Sort(a);
double l = 0, r = a[n - 1] * a[n - 1];
int count = 500;
double res = 0;
while (count > 0) {
double mid = (double)(l + r) / 2.0000;
if (isPossible(mid, a, n, k)) {
// cout << mid << " ";
res = mid;
l = mid;
}
else
r = mid;
count--;
}
// After calculating radius*radius for
// area multiply by pi(3.14) to get area
double p1 = res * 3.14159265359;
return p1;
}
// Driver Code
public static void Main()
{
// Number of pizza
int N = 6;
// Radius of all pizzas
int []arr = { 1, 1, 1, 2, 2, 3 };
// Number of friends
int K = 6;
// Function Call
Console.Write(maximumAreaPizza(arr, N, K));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
输出
7.06858
时间复杂度: O(N logN)
辅助空间: O(1)