📜  计划作业,以便每个服务器获得相等的负载

📅  最后修改于: 2021-05-06 18:13:32             🧑  作者: Mango

有n台服务器。每个服务器i当前正在处理一个(i)数量的请求。还有另一个数组b,其中b(i)代表调度到服务器i的传入请求的数量。重新安排传入的请求,以使每个服务器i在重新安排之后都拥有相等数量的请求。到服务器i的传入请求只能重新安排到服务器i-1,i,i + 1。如果没有这种重新安排的可能性,则在重新安排之后,输出-1,否则每个服务器保留的请求的打印数量。
例子:

Input : a = {6, 14, 21, 1}
        b = {15, 7, 10, 10}
Output : 21
b(0) scheduled to a(0) --> a(0) = 21
b(1) scheduled to a(1) --> a(1) = 21
b(2) scheduled to a(3) --> a(3) = 11
b(3) scheduled to a(3) --> a(3) = 21
a(2) remains unchanged --> a(2) = 21

Input : a = {1, 2, 3}
        b = {1, 100, 3}
Output : -1
No rescheduling will result in equal requests.
推荐:请首先在IDE上尝试您的方法,然后查看解决方案

方法:观察到数组b的每个元素总是总是恰好一次添加到数组a的任何一个元素。因此,数组b的所有元素的总和+旧数组a的所有元素的总和=新数组a的所有元素的总和。令该总和为S。新数组a的所有元素也相等。让每个新元素为x。如果数组a具有n个元素,则给出

x * n = S
  => x = S/n     ....(1)

因此,新数组a的所有相等元素都由eqn(1)给出。现在,要使每个a(i)等于x,我们需要将xa(i)添加到每个元素。我们将遍历整个数组a,并检查a(i)是否可以等于x。有多种可能性:
1. a(i)> x:在这种情况下,永远不能使a(i)等于x。因此输出-1。
2. a(i)+ b(i)+ b(i + 1)= x。只需将b(i)+ b(i + 1)添加到a(i),然后将b(i),b(i + 1)更新为零即可。
3. a(i)+ b(i)= x。将b(i)添加到a(i),并将b(i)更新为零。
4. a(i)+ b(i + 1)= x。将b(i + 1)添加到a(i),并将b(i + 1)更新为零。
数组a完全遍历后,检查数组b的所有元素是否为零。如果是,则打印a(0),否则打印-1。
为什么b(i)加法后更新为零?
考虑一个测试案例,其中b(i)既不添加到a(i-1)也不添加到a(i)。在那种情况下,我们必须将b(i)添加到a(i + 1)。因此,当我们开始对元素a(i)执行计算时,在数组a上进行迭代时,首先我们将元素b(i-1)添加到a(i)来考虑上述可能性。现在,如果b(i-1)已被添加到a(i-1)或a(i-2),那么在这种情况下,就无法将其添加到a(i)。因此,为避免b(i)的这种双重加法,将其更新为零。
逐步算法为:

1. Compute sum S and find x = S / n
2. Iterate over array a
3. for each element a(i) do:
   a(i) += b(i-1)
   b(i-1) = 0;
   if a(i) > x:
      break
   else:
     check for other three possibilities
     and update a(i) and b(i).
4. Check whether all elements of b(i) are
   zero or not.

执行:

C++
// CPP program to schedule jobs so that
// each server gets equal load.
#include 
using namespace std;
 
// Function to find new array a
int solve(int a[], int b[], int n)
{
    int i;
    long long int s = 0;
 
    // find sum S of both arrays a and b.
    for (i = 0; i < n; i++)
        s += (a[i] + b[i]);   
 
    // Single element case.
    if (n == 1)
        return a[0] + b[0];
 
    // This checks whether sum s can be divided
    // equally between all array elements. i.e.
    // whether all elements can take equal value
    // or not.
    if (s % n != 0)
        return -1;
 
    // Compute possible value of new array
    // elements.
    int x = s / n;
 
    for (i = 0; i < n; i++) {
 
        // Possibility 1
        if (a[i] > x)
            return -1;     
 
        // ensuring that all elements of
        // array b are used.
        if (i > 0) {
            a[i] += b[i - 1];
            b[i - 1] = 0;
        }
 
        // If a(i) already updated to x
        // move to next element in array a.
        if (a[i] == x)
            continue;
 
        // Possibility 2
        int y = a[i] + b[i];
        if (i + 1 < n)
            y += b[i + 1];
        if (y == x) {
            a[i] = y;
            b[i] = b[i + 1] = 0;
            continue;
        }
 
        // Possibility 3
        if (a[i] + b[i] == x) {
            a[i] += b[i];
            b[i] = 0;
            continue;
        }
 
        // Possibility 4
        if (i + 1 < n &&
            a[i] + b[i + 1] == x) {
            a[i] += b[i + 1];
            b[i + 1] = 0;
            continue;
        }
 
        // If a(i) can not be made equal
        // to x even after adding all
        // possible elements from b(i)
        // then print -1.
        return -1;
    }
 
    // check whether all elements of b
    // are used.
    for (i = 0; i < n; i++)
        if (b[i] != 0)
            return -1;   
 
    // Return the new array element value.
    return x;
}
 
int main()
{
    int a[] = { 6, 14, 21, 1 };
    int b[] = { 15, 7, 10, 10 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << solve(a, b, n);
    return 0;
}


Java
// Java program to schedule jobs so that
// each server gets equal load.
class GFG
{
 
// Function to find new array a
static int solve(int a[], int b[], int n)
{
    int i;
    int s = 0;
 
    // find sum S of both arrays a and b.
    for (i = 0; i < n; i++)
        s += (a[i] + b[i]);
 
    // Single element case.
    if (n == 1)
        return a[0] + b[0];
 
    // This checks whether sum s can be divided
    // equally between all array elements. i.e.
    // whether all elements can take equal value
    // or not.
    if (s % n != 0)
        return -1;
 
    // Compute possible value of new array
    // elements.
    int x = s / n;
 
    for (i = 0; i < n; i++)
    {
 
        // Possibility 1
        if (a[i] > x)
            return -1;    
 
        // ensuring that all elements of
        // array b are used.
        if (i > 0)
        {
            a[i] += b[i - 1];
            b[i - 1] = 0;
        }
 
        // If a(i) already updated to x
        // move to next element in array a.
        if (a[i] == x)
            continue;
 
        // Possibility 2
        int y = a[i] + b[i];
        if (i + 1 < n)
            y += b[i + 1];
        if (y == x)
        {
            a[i] = y;
            b[i]= 0;
            continue;
        }
 
        // Possibility 3
        if (a[i] + b[i] == x)
        {
            a[i] += b[i];
            b[i] = 0;
            continue;
        }
 
        // Possibility 4
        if (i + 1 < n &&
            a[i] + b[i + 1] == x)
        {
            a[i] += b[i + 1];
            b[i + 1] = 0;
            continue;
        }
 
        // If a(i) can not be made equal
        // to x even after adding all
        // possible elements from b(i)
        // then print -1.
        return -1;
    }
 
    // check whether all elements of b
    // are used.
    for (i = 0; i < n; i++)
        if (b[i] != 0)
            return -1;
 
    // Return the new array element value.
    return x;
}
 
// Driver code
public static void main(String[] args)
{
    int a[] = { 6, 14, 21, 1 };
    int b[] = { 15, 7, 10, 10 };
    int n = a.length;
    System.out.println(solve(a, b, n));
}
}
 
// This code contributed by Rajput-Ji


Python3
# Python3 program to schedule jobs so that
# each server gets an equal load.
 
# Function to find new array a
def solve(a, b, n):
 
    s = 0
 
    # find sum S of both arrays a and b.
    for i in range(0, n):
        s += a[i] + b[i]    
 
    # Single element case.
    if n == 1:
        return a[0] + b[0]
 
    # This checks whether sum s can be divided
    # equally between all array elements. i.e.
    # whether all elements can take equal value
    # or not.
    if s % n != 0:
        return -1
 
    # Compute possible value of new
    # array elements.
    x = s // n
 
    for i in range(0, n):
 
        # Possibility 1
        if a[i] > x:
            return -1   
 
        # ensuring that all elements of
        # array b are used.
        if i > 0:
            a[i] += b[i - 1]
            b[i - 1] = 0
         
        # If a(i) already updated to x
        # move to next element in array a.
        if a[i] == x:
            continue
 
        # Possibility 2
        y = a[i] + b[i]
        if i + 1 < n:
            y += b[i + 1]
         
        if y == x:
            a[i] = y
            b[i] = 0
            if i + 1 < n: b[i + 1] = 0
            continue
         
        # Possibility 3
        if a[i] + b[i] == x:
            a[i] += b[i]
            b[i] = 0
            continue
         
        # Possibility 4
        if i + 1 < n and a[i] + b[i + 1] == x:
            a[i] += b[i + 1]
            b[i + 1] = 0
            continue
         
        # If a(i) can not be made equal
        # to x even after adding all
        # possible elements from b(i)
        # then print -1.
        return -1
     
    # check whether all elements of b
    # are used.
    for i in range(0, n):
        if b[i] != 0:
            return -1   
 
    # Return the new array element value.
    return x
 
# Driver Code
if __name__ == "__main__":
 
    a = [6, 14, 21, 1]
    b = [15, 7, 10, 10]
    n = len(a)
    print(solve(a, b, n))
     
# This code is contributed by Rituraj Jain


C#
// C# program to schedule jobs so that
// each server gets equal load.
using System;
 
class GFG
{
 
// Function to find new array a
static int solve(int []a, int []b, int n)
{
    int i;
    int s = 0;
 
    // find sum S of both arrays a and b.
    for (i = 0; i < n; i++)
        s += (a[i] + b[i]);
 
    // Single element case.
    if (n == 1)
        return a[0] + b[0];
 
    // This checks whether sum s can be divided
    // equally between all array elements. i.e.
    // whether all elements can take equal value
    // or not.
    if (s % n != 0)
        return -1;
 
    // Compute possible value of new array
    // elements.
    int x = s / n;
 
    for (i = 0; i < n; i++)
    {
 
        // Possibility 1
        if (a[i] > x)
            return -1;
 
        // ensuring that all elements of
        // array b are used.
        if (i > 0)
        {
            a[i] += b[i - 1];
            b[i - 1] = 0;
        }
 
        // If a(i) already updated to x
        // move to next element in array a.
        if (a[i] == x)
            continue;
 
        // Possibility 2
        int y = a[i] + b[i];
        if (i + 1 < n)
            y += b[i + 1];
        if (y == x)
        {
            a[i] = y;
            b[i]= 0;
            continue;
        }
 
        // Possibility 3
        if (a[i] + b[i] == x)
        {
            a[i] += b[i];
            b[i] = 0;
            continue;
        }
 
        // Possibility 4
        if (i + 1 < n &&
            a[i] + b[i + 1] == x)
        {
            a[i] += b[i + 1];
            b[i + 1] = 0;
            continue;
        }
 
        // If a(i) can not be made equal
        // to x even after adding all
        // possible elements from b(i)
        // then print -1.
        return -1;
    }
 
    // check whether all elements of b
    // are used.
    for (i = 0; i < n; i++)
        if (b[i] != 0)
            return -1;
 
    // Return the new array element value.
    return x;
}
 
// Driver code
public static void Main(String[] args)
{
    int []a = { 6, 14, 21, 1 };
    int []b = { 15, 7, 10, 10 };
    int n = a.Length;
    Console.WriteLine(solve(a, b, n));
}
}
 
// This code has been contributed by 29AjayKumar


Javascript


输出:

21

时间复杂度: O(n)
辅助空间: O(1)如果不允许我们修改原始数组,则O(n)