给定三个整数N , E和O。任务是找到一个大小为N的数组,以使sum的奇数和奇数的子数组的数量分别为E和O。
例子:
Input: N = 3, E = 2, O = 4
Output: 0 1 0
There are total 6 sub-arrays: {0}, {1}, {0}, {0, 1}, {1, 0}, {0, 1, 0}.
Their sums are {0, 1, 0, 1, 1, 1} respectively.
2 of them are even and 4 of them are odd.
Input: N = 3, E = 0, O = 6
Output: -1
天真的方法:使用位掩码来生成数组中0和1的所有组合。对于每个组合,我们计算偶数和奇数子数组的数量。如果它们等于给定值,那么它是正确的组合,我们打印
数组。
对于这种方法,将生成所有需要的集合对于每种组合,我们找到计算成本的子阵列数量 。
高效的方法:众所周知,数组的PrefixSums。因此,我们将计算偶数PrefixSum和奇数PrefixSum的数量。如果我们以某种方式知道分别具有奇数和偶数奇偶校验的prefixSums的数量,我们可以相应地创建任何有效的数组,前提是oddPrefixSums和evenPrefixSums的总数为N + 1。
示例:如果我们有3个evenPrefixSums和2个奇数PrefixSums,我们可以创建一个数组[0,0,1,0]。诀窍是在放置(evenPrefixSums – 1)零之后放置唯一的1。所有剩余的prefixSums显然都是奇校验。
以下等式成立。
evenPrefixSums + oddPrefixSums = N + 1
由于prefixSum_i – prefixSum_j有助于连续子数组的总和,因此两者都应具有不同的奇偶校验。因此,具有奇数奇偶性的连续子数组的数目将为C(evenPrefixSums,1)* C(oddPrefixSums,1)。这引起了另一个方程。
evenPrefixSums * oddPrefixSums = O
我们可以形成一个二次方程式,并将其求解以获得相应的值。如果找不到任何有效值,则输出-1。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
#include
using namespace std;
// Function to generate and print the required array
void CreateArray(int N, int even, int odd)
{
int temp = -1;
int OddPreSums;
// Find the number of odd prefix sums
for (int i = 0; i <= N + 1; i++) {
if (i * ((N + 1) - i) == odd) {
temp = 0;
OddPreSums = i;
break;
}
}
// If no odd prefix sum found
if (temp == -1) {
cout << temp << endl;
}
else {
// Calculating the number of even prefix sums
int EvenPreSums = (N + 1) - OddPreSums;
int e = 1;
int o = 0;
// Stores the current prefix sum
int CurrSum = 0;
for (int i = 0; i < N; i++) {
// If current prefix sum is even
if (CurrSum % 2 == 0) {
// Print 0 until e = EvenPreSums - 1
if (e < EvenPreSums) {
e++;
cout << "0 ";
}
else {
o++;
// Print 1 when e = EvenPreSums
cout << "1 ";
CurrSum++;
}
}
else {
if (e < EvenPreSums) {
e++;
cout << "1 ";
CurrSum++;
}
else {
o++;
// Print 0 for rest of the values
cout << "0 ";
}
}
}
cout << endl;
}
}
// Driver code
int main()
{
int N = 15;
int even = 60, odd = 60;
CreateArray(N, even, odd);
return 0;
}
Java
// Java implementation of the approach
import java.io.*;
class GFG {
// Function to generate and print the required array
static void CreateArray(int N, int even, int odd)
{
int EvenPreSums = 1;
int temp = -1;
int OddPreSums = 0;
// Find the number of odd prefix sums
for (int i = 0; i <= N + 1; i++) {
if (i * ((N + 1) - i) == odd) {
temp = 0;
OddPreSums = i;
break;
}
}
// If no odd prefix sum found
if (temp == -1) {
System.out.println(temp);
}
else {
// Calculating the number of even prefix sums
EvenPreSums = ((N + 1) - OddPreSums);
int e = 1;
int o = 0;
// Stores the current prefix sum
int CurrSum = 0;
for (int i = 0; i < N; i++) {
// If current prefix sum is even
if (CurrSum % 2 == 0) {
// Print 0 until e = EvenPreSums - 1
if (e < EvenPreSums) {
e++;
System.out.print("0 ");
}
else {
o++;
// Print 1 when e = EvenPreSums
System.out.print("1 ");
CurrSum++;
}
}
else {
if (e < EvenPreSums) {
e++;
System.out.print("1 ");
CurrSum++;
}
else {
o++;
// Print 0 for rest of the values
System.out.print("0 ");
}
}
}
System.out.println();
}
}
// Driver code
public static void main(String[] args)
{
int N = 15;
int even = 60, odd = 60;
CreateArray(N, even, odd);
}
}
// This code is contributed by akt_mit
Python3
# Python 3 implementation of the approach
# Function to generate and print
# the required array
def CreateArray(N, even, odd):
temp = -1
# Find the number of odd prefix sums
for i in range(N + 2):
if (i * ((N + 1) - i) == odd):
temp = 0
OddPreSums = i
break
# If no odd prefix sum found
if (temp == -1):
print(temp)
else:
# Calculating the number
# of even prefix sums
EvenPreSums = (N + 1) - OddPreSums
e = 1
o = 0
# Stores the current prefix sum
CurrSum = 0
for i in range(N):
# If current prefix sum is even
if (CurrSum % 2 == 0):
# Print 0 until e = EvenPreSums - 1
if (e < EvenPreSums):
e += 1
print("0 ", end = "")
else:
o += 1
# Print 1 when e = EvenPreSums
print("1 ", end = "")
CurrSum += 1
else:
if (e < EvenPreSums):
e += 1
print("1 ")
CurrSum += 1
else:
o += 1
# Print 0 for rest of the values
print("0 ", end = "")
print("\n", end = "")
# Driver code
if __name__ == '__main__':
N = 15
even = 60
odd = 60
CreateArray(N, even, odd)
# This code is contributed by
# Surendra_Gangwar
C#
// C# implementation of the approach
using System;
class GFG {
// Function to generate and print the required array
static void CreateArray(int N, int even, int odd)
{
int EvenPreSums = 1;
int temp = -1;
int OddPreSums = 0;
// Find the number of odd prefix sums
for (int i = 0; i <= N + 1; i++) {
if (i * ((N + 1) - i) == odd) {
temp = 0;
OddPreSums = i;
break;
}
}
// If no odd prefix sum found
if (temp == -1) {
Console.WriteLine(temp);
}
else {
// Calculating the number of even prefix sums
EvenPreSums = ((N + 1) - OddPreSums);
int e = 1;
int o = 0;
// Stores the current prefix sum
int CurrSum = 0;
for (int i = 0; i < N; i++) {
// If current prefix sum is even
if (CurrSum % 2 == 0) {
// Print 0 until e = EvenPreSums - 1
if (e < EvenPreSums) {
e++;
Console.Write("0 ");
}
else {
o++;
// Print 1 when e = EvenPreSums
Console.Write("1 ");
CurrSum++;
}
}
else {
if (e < EvenPreSums) {
e++;
Console.Write("1 ");
CurrSum++;
}
else {
o++;
// Print 0 for rest of the values
Console.Write("0 ");
}
}
}
Console.WriteLine();
}
}
// Driver code
static public void Main()
{
int N = 15;
int even = 60, odd = 60;
CreateArray(N, even, odd);
}
}
// This code is contributed by Tushil
PHP
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0