📜  最少 1s 提供力量,使整个阵列强大

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

最少 1s 提供力量,使整个阵列强大

给定一个二进制数组和一个整数 k,其中每个 1 都有权力,它可以将权力借给邻居和它自己。值为 1 的像元可以在距离 < k的范围内提供电力。任务是找到最小数量的 1 需要提供能量,以便所有细胞都变得强大。
如果无法使整个数组变得强大,则返回 -1。
例子:

Input  : arr[] = {0, 1, 1, 1, 1, 0}                
             K = 2 
Output : 2
arr[1] and arr[5] need to lend

Input  :  arr[] = {1, 0, 1, 0, 0, 1, 0, 0, 0, 1}        
              K = 3
Output : 3
a[2], a[5] and a[9] lend to their right side zeros.


Input  :  arr[] = {1, 1, 1}        
              K = 2
Output : 1
arr[1] need to lend power to all cells.

一个简单的解决方案是尝试所有可能的 1 组合,从一个 1 开始,然后是两个 1,依此类推,直到我们找到一个组合使整个数组变得强大。
一个有效的解决方案是基于观察到每个单元的距离 k 内应该有一个 1。我们对数组进行预处理并创建一个辅助数组,该数组存储左侧最接近 1 的索引。我们遍历整个数组并找到当前单元k距离内最近的左边1的索引。如果没有左 1,我们返回 -1。否则,我们增加 ans 并在 k 距离后移动到下一个单元格。

C++
// C++ program to minimum of number of lendings
// by 1s.
#include 
using namespace std;
 
int minLendings(int arr[], int n, int k)
{
    // Create an auxiliary array and fill
    // indexes of closest 1s on left side.
    int leftOne[n];
    int oneInd = -1;
    for (int i = 0; i < n; i++) {
        if (arr[i] == 1)
            oneInd = i;
        leftOne[i] = oneInd;
    }
 
    // Traverse the array from left side. If
    // current element has a 1 on
    int ans = 0;
    for (int i = 0; i < n;) {
  
        // Find index of closest 1 after shift of
        // k-1 or end whichever is closer.
        int pos = leftOne[min(i + k - 1, n - 1)];
 
        // If there is no closest 1 within allowed
        // range.
        if (pos == -1 || pos + k <= i)
            return -1;
 
        // If a closest 1 is found, check after k
        // jumps and increment answer.
        i = pos + k;
        ans++;
    }
    return ans;
}
 
// Driver code
int main()
{
    int arr[] = { 0, 1, 1, 1, 1, 0 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 2;
    cout << minLendings(arr, n, k);
    return 0;
}


Java
// Java program to minimum of number of
// lendings by 1s.
import java.math.*;
 
class GFG {
 
static int minLendings(int arr[], int n, int k)
{
    // Create an auxiliary array and fill
    // indexes of closest 1s on left side.
    int leftOne[] = new int[n];
    int oneInd = -1;
    for (int i = 0; i < n; i++) {
        if (arr[i] == 1)
            oneInd = i;
        leftOne[i] = oneInd;
    }
 
    // Traverse the array from left side. If
    // current element has a 1 on
    int ans = 0;
    for (int i = 0; i < n;) {
 
        // Find index of closest 1 after shift of
        // k-1 or end whichever is closer.
        int pos = leftOne[Math.min(i + k - 1, n - 1)];
 
        // If there is no closest 1 within
        // allowed range.
        if (pos == -1 || pos + k <= i)
            return -1;
 
        // If a closest 1 is found, check after k
        // jumps and increment answer.
        i = pos + k;
        ans++;
    }
    return ans;
}
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { 0, 1, 1, 1, 1, 0 };
    int n = arr.length;
    int k = 2;
    System.out.println(minLendings(arr, n, k));
}
}
 
// This code is contributed by Prerna Saini


Python3
# Python3 program to minimum
# of number of lendings by 1s.
 
def minLendings(arr, n, k):
 
    # Create an auxiliary array and fill
    # indexes of closest 1s on left side.
    leftOne = [0 for i in range(n + 1)]
    oneInd = -1
     
    for i in range(n):
        if (arr[i] == 1):
            oneInd = i
        leftOne[i] = oneInd
 
    # Traverse the array from left side.
    # If current element has a 1 on
    ans = 0; i = 0
     
    while(i < n):
 
        # Find index of closest 1 after shift of
        # k-1 or end whichever is closer.
        pos = leftOne[min(i + k - 1, n - 1)]
 
        # If there is no closest 1 
        # within allowed range.
        if (pos == -1 or pos + k <= i):
            return -1
 
        # If a closest 1 is found, check after k
        # jumps and increment answer.
        i = pos + k
        ans += 1
     
    return ans
 
# Driver program
arr = [ 0, 1, 1, 1, 1, 0 ]
n = len(arr)
k = 2
print(minLendings(arr, n, k))
 
# This code is contributed by Anant Agarwal.


C#
// C# program to minimum of number of
// lendings by 1s.
using System;
 
class GFG {
 
    static int minLendings(int []arr, int n, int k)
    {
         
        // Create an auxiliary array and fill
        // indexes of closest 1s on left side.
        int []leftOne = new int[n];
        int oneInd = -1;
        for (int i = 0; i < n; i++)
        {
            if (arr[i] == 1)
                oneInd = i;
            leftOne[i] = oneInd;
        }
     
        // Traverse the array from left side.
        // If current element has a 1 on
        int ans = 0;
        for (int i = 0; i < n;)
        {
     
            // Find index of closest 1 after
            // shift of k-1 or end whichever
            // is closer.
            int pos = leftOne[Math.Min(i + k - 1,
                                          n - 1)];
     
            // If there is no closest 1 within
            // allowed range.
            if (pos == -1 || pos + k <= i)
                return -1;
     
            // If a closest 1 is found, check
            // after k jumps and increment answer.
            i = pos + k;
            ans++;
        }
         
        return ans;
    }
     
    // Driver code
    public static void Main()
    {
        int []arr = { 0, 1, 1, 1, 1, 0 };
        int n = arr.Length;
        int k = 2;
         
        Console.WriteLine(minLendings(arr, n, k));
    }
}
 
// This code is contributed by vt_m.


PHP


Javascript


输出 :

2