📌  相关文章
📜  求每个正元素的 K 个相邻元素递增 M 次后的数组和

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

求每个正元素的 K 个相邻元素递增 M 次后的数组和

给定一个包含N个整数的循环数组arr[] 和两个整数MK ,任务是在执行M次操作后找到数组元素arr[]的和,使得在每次操作中,将所有正数组元素的相邻数组元素递增K ,即如果arr[i ] > 0 ,然后将arr[i – 1]arr[i + 1]的值增加K

例子:

方法:可以根据以下观察解决给定的问题:

  • 任何非零元素将始终在一次移动中将数组的总和增加2 * K。
  • 将整数从0增加到非零值所需的移动次数始终等于最近的非零元素的距离。

请按照以下步骤解决问题:

  • 创建一个数组steps[] ,它存储当前元素与最近的非零元素的距离。
  • 创建一个函数nearestLeft()以查找最近的非零元素的索引,同时使用本文讨论的方法沿左方向遍历数组。
  • 类似地,创建一个函数nearestRight()来查找最近的非零元素的索引,同时以正确的方向遍历数组。
  • 将第i元素的值从0递增所需的操作次数由steps[i]给出,之后,每次操作后它将为最终总和贡献2 * K。因此,第i整数在M次操作后的最终总和中的总贡献为2 * K * (M – steps[i])
  • 遍历[1, N]范围内的数组arr[]并跟踪变量中每个索引贡献的总和,比如sum
  • 完成上述步骤后,打印sum的值作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to find the nearest non-zero
// element in the left direction
void nearestLeft(int arr[], int N,
                 vector& steps)
{
    // Stores the index of the first element
    // greater than 0 from the right side
    int L = -N;
 
    // Traverse the array in the range [1, N]
    for (int i = N - 1; i >= 0; i--) {
        // Check arr[i] is greater than 0
        if (arr[i] > 0) {
            // Update the value of L
            L = -(N - i);
            break;
        }
    }
 
    // Traverse the array from the left side
    for (int i = 0; i < N; i++) {
        // Check arr[i] is greater than 0
        if (arr[i] > 0) {
            // Update the value of L
            L = i;
        }
 
        // Update the value of steps[i]
        steps[i] = i - L;
    }
}
 
// Function to find the nearest non-zero
// element in the right direction
void nearestRight(int arr[], int N,
                  vector& steps)
{
    // Stores the index of the first element
    // greater than 0 from the left side
    int R = 2 * N;
 
    // Traverse the array from the left side
    for (int i = 0; i < N; i++) {
 
        // Check arr[i] is greater than 0
        if (arr[i] > 0) {
 
            // Update the value of R
            R = N + i;
            break;
        }
    }
 
    // Traverse the array from the right side
    for (int i = N - 1; i >= 0; i--) {
        // Check arr[i] is greater than 0
        if (arr[i] > 0) {
            // Update the value of R
            R = i;
        }
 
        // Update the value of steps[i]
        steps[i] = min(steps[i], R - i);
    }
}
 
// Function to find the sum of the array
// after the given operation M times
int findSum(int arr[], int N, int M, int K)
{
    // Stores the distance of the nearest
    // non zero element.
    vector steps(N);
 
    // Stores sum of the initial array arr[]
    int sum = accumulate(arr, arr + N, 0);
 
    if (sum == 0) {
        return 0;
    }
 
    nearestLeft(arr, N, steps);
    nearestRight(arr, N, steps);
 
    // Traverse the array from the left side
    for (int i = 0; i < N; i++)
 
        // Update the value of sum
        sum += 2 * K * max(0, M - steps[i]);
 
    // Print the total sum of the array
    return sum;
}
 
// Driver Code
int main()
{
    int arr[] = { 0, 1, 0, 1, 0, 0 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int M = 2;
    int K = 1;
 
    cout << findSum(arr, N, M, K);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to find the nearest non-zero
// element in the left direction
static void nearestLeft(int arr[], int N,
                 int[] steps)
{
   
    // Stores the index of the first element
    // greater than 0 from the right side
    int L = -N;
 
    // Traverse the array in the range [1, N]
    for (int i = N - 1; i >= 0; i--)
    {
       
        // Check arr[i] is greater than 0
        if (arr[i] > 0)
        {
           
            // Update the value of L
            L = -(N - i);
            break;
        }
    }
 
    // Traverse the array from the left side
    for (int i = 0; i < N; i++)
    {
       
        // Check arr[i] is greater than 0
        if (arr[i] > 0)
        {
           
            // Update the value of L
            L = i;
        }
 
        // Update the value of steps[i]
        steps[i] = i - L;
    }
}
 
// Function to find the nearest non-zero
// element in the right direction
static void nearestRight(int arr[], int N,
                 int[] steps)
{
   
    // Stores the index of the first element
    // greater than 0 from the left side
    int R = 2 * N;
 
    // Traverse the array from the left side
    for (int i = 0; i < N; i++) {
 
        // Check arr[i] is greater than 0
        if (arr[i] > 0) {
 
            // Update the value of R
            R = N + i;
            break;
        }
    }
 
    // Traverse the array from the right side
    for (int i = N - 1; i >= 0; i--)
    {
       
        // Check arr[i] is greater than 0
        if (arr[i] > 0)
        {
           
            // Update the value of R
            R = i;
        }
 
        // Update the value of steps[i]
        steps[i] = Math.min(steps[i], R - i);
    }
}
static int accumulate(int[] arr, int start, int end){
    int sum = 0;
    for(int i= 0; i < arr.length; i++)
        sum += arr[i];
    return sum;
}
   
// Function to find the sum of the array
// after the given operation M times
static int findSum(int arr[], int N, int M, int K)
{
   
    // Stores the distance of the nearest
    // non zero element.
    int []steps = new int[N];
 
    // Stores sum of the initial array arr[]
    int sum = accumulate(arr, 0, N);
 
    if (sum == 0) {
        return 0;
    }
 
    nearestLeft(arr, N, steps);
    nearestRight(arr, N, steps);
 
    // Traverse the array from the left side
    for (int i = 0; i < N; i++)
 
        // Update the value of sum
        sum += 2 * K * Math.max(0, M - steps[i]);
 
    // Print the total sum of the array
    return sum;
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 0, 1, 0, 1, 0, 0 };
    int N = arr.length;
    int M = 2;
    int K = 1;
 
    System.out.print(findSum(arr, N, M, K));
}
}
 
// This code is contributed by shikhasingrajput


Python3
# Python3 program for the above approach
 
# Function to find the nearest non-zero
# element in the left direction
def nearestLeft(arr, N, steps):
     
    # Stores the index of the first element
    # greater than 0 from the right side
    L = -N
 
    # Traverse the array in the range [1, N]
    for i in range(N - 1, -1, -1):
         
        # Check arr[i] is greater than 0
        if (arr[i] > 0):
             
            # Update the value of L
            L = -(N - i)
            break
 
    # Traverse the array from the left side
    for i in range(N):
         
        # Check arr[i] is greater than 0
        if (arr[i] > 0):
             
            # Update the value of L
            L = i
 
        # Update the value of steps[i]
        steps[i] = i - L
 
# Function to find the nearest non-zero
# element in the right direction
def nearestRight(arr, N, steps):
 
    # Stores the index of the first element
    # greater than 0 from the left side
    R = 2 * N
 
    # Traverse the array from the left side
    for i in range(N):
 
        # Check arr[i] is greater than 0
        if (arr[i] > 0):
 
            # Update the value of R
            R = N + i
            break
 
    # Traverse the array from the right side
    for i in range(N - 1, -1, -1):
         
        # Check arr[i] is greater than 0
        if (arr[i] > 0):
             
            # Update the value of R
            R = i
 
        # Update the value of steps[i]
        steps[i] = min(steps[i], R - i)
 
# Function to find the sum of the array
# after the given operation M times
def findSum(arr, N, M, K):
 
    # Stores the distance of the nearest
    # non zero element.
    steps = [0] * N
 
    # Stores sum of the initial array arr[]
    s = sum(arr)
 
    if (s == 0):
        return 0
 
    nearestLeft(arr, N, steps)
    nearestRight(arr, N, steps)
 
    # Traverse the array from the left side
    for i in range(N):
 
        # Update the value of sum
        s += 2 * K * max(0, M - steps[i])
 
    # Print the total sum of the array
    return s
 
# Driver Code
if __name__ == "__main__":
 
    arr = [ 0, 1, 0, 1, 0, 0 ]
    N = len(arr)
    M = 2
    K = 1
 
    print(findSum(arr, N, M, K))
 
# This code is contributed by ukasp


C#
// C# program for the above approach
using System;
public class GFG{
 
// Function to find the nearest non-zero
// element in the left direction
static void nearestLeft(int []arr, int N,
                 int[] steps)
{
   
    // Stores the index of the first element
    // greater than 0 from the right side
    int L = -N;
 
    // Traverse the array in the range [1, N]
    for (int i = N - 1; i >= 0; i--)
    {
       
        // Check arr[i] is greater than 0
        if (arr[i] > 0)
        {
           
            // Update the value of L
            L = -(N - i);
            break;
        }
    }
 
    // Traverse the array from the left side
    for (int i = 0; i < N; i++)
    {
       
        // Check arr[i] is greater than 0
        if (arr[i] > 0)
        {
           
            // Update the value of L
            L = i;
        }
 
        // Update the value of steps[i]
        steps[i] = i - L;
    }
}
 
// Function to find the nearest non-zero
// element in the right direction
static void nearestRight(int []arr, int N,
                 int[] steps)
{
   
    // Stores the index of the first element
    // greater than 0 from the left side
    int R = 2 * N;
 
    // Traverse the array from the left side
    for (int i = 0; i < N; i++) {
 
        // Check arr[i] is greater than 0
        if (arr[i] > 0) {
 
            // Update the value of R
            R = N + i;
            break;
        }
    }
 
    // Traverse the array from the right side
    for (int i = N - 1; i >= 0; i--)
    {
       
        // Check arr[i] is greater than 0
        if (arr[i] > 0)
        {
           
            // Update the value of R
            R = i;
        }
 
        // Update the value of steps[i]
        steps[i] = Math.Min(steps[i], R - i);
    }
}
static int accumulate(int[] arr, int start, int end){
    int sum = 0;
    for(int i= 0; i < arr.Length; i++)
        sum += arr[i];
    return sum;
}
   
// Function to find the sum of the array
// after the given operation M times
static int findSum(int []arr, int N, int M, int K)
{
   
    // Stores the distance of the nearest
    // non zero element.
    int []steps = new int[N];
 
    // Stores sum of the initial array []arr
    int sum = accumulate(arr, 0, N);
 
    if (sum == 0) {
        return 0;
    }
 
    nearestLeft(arr, N, steps);
    nearestRight(arr, N, steps);
 
    // Traverse the array from the left side
    for (int i = 0; i < N; i++)
 
        // Update the value of sum
        sum += 2 * K * Math.Max(0, M - steps[i]);
 
    // Print the total sum of the array
    return sum;
}
 
// Driver Code
public static void Main(String[] args)
{
    int []arr = { 0, 1, 0, 1, 0, 0 };
    int N = arr.Length;
    int M = 2;
    int K = 1;
 
    Console.Write(findSum(arr, N, M, K));
}
}
 
// This code is contributed by shikhasingrajput


Javascript


输出:
16

时间复杂度: O(N)
辅助空间: O(N)