求每个正元素的 K 个相邻元素递增 M 次后的数组和
给定一个包含N个整数的循环数组arr[] 和两个整数M和K ,任务是在执行M次操作后找到数组元素arr[]的和,使得在每次操作中,将所有正数组元素的相邻数组元素递增K ,即如果arr[i ] > 0 ,然后将arr[i – 1]和arr[i + 1]的值增加K 。
例子:
Input: arr[] = {0, 1, 0, 1, 0, 0}, M = 2, K = 1
Output: 16
Explanation:
In the 1st operation after incrementing the adjacent array elements of arr[] > 0, the given array modifies to arr[] = {1, 1, 2, 1, 1, 0}.
In the 2nd operation after incrementing the adjacent array elements of arr[] > 0, the given array modifies to arr[] = {2, 3, 4, 3, 2, 2}. So the sum of all elements of arr[] is 16.
Input: arr[] = {1, 2, 3}, M = 10, K = 2
Output: 126
方法:可以根据以下观察解决给定的问题:
- 任何非零元素将始终在一次移动中将数组的总和增加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)