📜  找到要从披萨上切下的最大一块,这样每个披萨至少有一块面积相同

📅  最后修改于: 2022-05-13 01:56:06.585000             🧑  作者: Mango

找到要从披萨上切下的最大一块,这样每个披萨至少有一块面积相同

给定一个数组arr[]表示圆形披萨的半径和一个整数N表示朋友的数量。任务是计算可以从比萨饼上切下的最大一块,这样每个朋友都可以得到一块面积相同的比萨饼。
不允许用一个以上的比萨做一片,每个朋友只能得到一份比萨。

例子:

方法:这个问题可以通过使用二分搜索来解决。请按照以下步骤解决给定的问题。

  • 对数组进行排序,这将有助于对其使用二进制搜索。
  • 现在,这个人可以拥有的最大面积是maxArea=π* a[n-1]*a[n-1] (圆的面积 - π*r 2 )。
  • 设该人可以拥有的最小面积为minArea=0。
  • 现在在这个给定的范围上应用二分搜索。
  • 由于π是常数,因此应用从minArea=0maxArea= 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)