给定一个整数N ,任务是将前N个自然数(总是8的倍数)的平方划分为两个集合,以使子集和的差最小。将两个子集都打印为必需的答案。
例子:
Input: N = 8
Output:
0
1 16 36 49
4 9 25 64
Explanation: Squares of first N natural numbers are {1, 4, 9, 16, 25, 36, 49, 64}
Subsets {1, 16, 36, 49} and {4, 9, 25, 64} have sum 102. Therefore, difference of their sums is 0.
Input: N = 16
Output:
0
1 16 36 49 81 144 196 225
4 9 25 64 100 121 169 256
天真的方法:想法是生成所有可能的子集对,将它们之间的前N个自然数的平方分开,并计算其子集之和之和的子集。打印发现其总和之差最小的那对子集。
时间复杂度: O(N * 2 N )
辅助空间: O(1)
高效方法:为了优化上述方法,其思想是使用连续平方数之和的数学属性。请注意,始终可以将8个连续的平方数分为2组,以使它们的子集和差为0 。
Proof:
8 contiguous square numbers can be divided into 2 subsets having difference of their sum as 0.
4 contiguous square numbers can be represented as k2, (k + 1)2, (k + 2)2 and (k + 3)2.
Let’s take 1st and 4th element in subset A. Therefore,
Sum of A = k2 + (k+3)2
= 2k2 + 6k + 9
Let’s take 2nd and 3rd element in subset B. Therefore,
Sum of B = (k + 1)2 + (k + 2)2
= 2k2 + 6k + 5
Subset difference = Sum of A – Sum of B = 4
Hence, 4 contiguous square numbers can be divided into 2 subsets having difference of their sum as 4.
Now, Lets say, the array of contiguous square is arr[] = {a1, a2, a3, a4, a5, a6, a7, a8}.
From the above property, it can be written that:
a1 + a4 – (a2 + a3) = 4 and
a5 + a8 – (a6 + a7) = 4
Subtracting the above equations:
a1 + a4 – (a2 + a3) – (a5 + a8 – (a6 + a7)) = 0
Therefore, (a1 + a4 + a6 + a7) – (a2 + a3 + a5 + a8) = 0
Hence, 8 contiguous square numbers can be divided into 2 subsets having difference as 0.
请按照以下步骤解决问题:
- 初始化变量以存储最小子集差异并将其声明为0 。
- 初始化变量cnt以存储大小为8的块数,然后将N除以8并将其存储在变量cnt中。
- 通过串联字符串“ ABBABAAB”来初始化字符串分区并存储N个元素的分区模式, cnt次数,其中“ ABBABAAB”代表大小为8的子数组中每个元素必须进入的子集。
- 初始化2个向量A和B以存储子集A和子集B的元素。
- 如果pattern [i]为‘A’,则在[0,N – 1]范围内循环循环,并将(i + 1) 2插入向量A中。否则,将(i +1) 2插入向量B中。
- 完成上述步骤后,打印最小子集差,向量A和向量B。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to partition squares of N
// natural number in two subset
void minimumSubsetDifference(int N)
{
// Store the count of blocks of size 8
int blockOfSize8 = N / 8;
// Partition of block of 8 element
string str = "ABBABAAB";
// Store the minimum subset difference
int subsetDifference = 0;
// Partition of N elements to minimize
// their subset sum difference
string partition = "";
while (blockOfSize8--) {
partition += str;
}
// Store elements of subset A and B
vector A, B;
for (int i = 0; i < N; i++) {
// If element is of type A
if (partition[i] == 'A') {
A.push_back((i + 1) * (i + 1));
}
// If the element is of type B
else {
B.push_back((i + 1) * (i + 1));
}
}
// Print the minimum subset difference
cout << subsetDifference << "\n";
// Print the first subset
for (int i = 0; i < A.size(); i++)
cout << A[i] << " ";
cout << "\n";
// Print the second subset
for (int i = 0; i < B.size(); i++)
cout << B[i] << " ";
}
// Driver Code
int main()
{
int N = 8;
// Function Call
minimumSubsetDifference(N);
return 0;
}
Java
// Java program for the above approach
import java.util.Arrays;
class GFG{
// Function to partition squares of N
// natural number in two subset
static void minimumSubsetDifference(int N)
{
// Store the count of blocks of size 8
int blockOfSize8 = N / 8;
// Partition of block of 8 element
String str = "ABBABAAB";
// Store the minimum subset difference
int subsetDifference = 0;
// Partition of N elements to minimize
// their subset sum difference
String partition = "";
while (blockOfSize8-- > 0)
{
partition += str;
}
// Store elements of subset A and B
int A[] = new int[N];
int B[] = new int[N];
int x = 0, y = 0;
for(int i = 0; i < N; i++)
{
// If element is of type A
if (partition.charAt(i) == 'A')
{
A[x++] = ((i + 1) * (i + 1));
}
// If the element is of type B
else
{
B[y++] = ((i + 1) * (i + 1));
}
}
// Print the minimum subset difference
System.out.println(subsetDifference);
// Print the first subset
for(int i = 0; i < x; i++)
System.out.print(A[i] + " ");
System.out.println();
// Print the second subset
for(int i = 0; i < y; i++)
System.out.print(B[i] + " ");
}
// Driver Code
public static void main(String[] args)
{
int N = 8;
// Function Call
minimumSubsetDifference(N);
}
}
// This code is contributed by shailjapriya
Python3
# Python3 program for the above approach
# Function to partition squares of N
# natural number in two subset
def minimumSubsetDifference(N):
# Store the count of blocks of size 8
blockOfSize8 = N // 8
# Partition of block of 8 element
str = "ABBABAAB"
# Store the minimum subset difference
subsetDifference = 0
# Partition of N elements to minimize
# their subset sum difference
partition = ""
while blockOfSize8 != 0:
partition = partition + str
blockOfSize8 = blockOfSize8 - 1
# Store elements of subset A and B
A = []
B = []
for i in range(N):
# If element is of type A
if partition[i] == 'A':
A.append((i + 1) * (i + 1))
# If the element is of type B
else:
B.append((i + 1) * (i + 1))
# Print the minimum subset difference
print(subsetDifference)
# Print the first subset
for i in A:
print(i, end = " ")
print()
# Print the second subset
for i in B:
print(i, end = " ")
# Driver Code
N = 8
# Function call
minimumSubsetDifference(N)
# This code is contributed by shailjapriya
C#
// C# program for the above approach
using System;
class GFG{
// Function to partition squares of N
// natural number in two subset
static void minimumSubsetDifference(int N)
{
// Store the count of blocks of size 8
int blockOfSize8 = N / 8;
// Partition of block of 8 element
string str = "ABBABAAB";
// Store the minimum subset difference
int subsetDifference = 0;
// Partition of N elements to minimize
// their subset sum difference
string partition = "";
while (blockOfSize8-- > 0)
{
partition += str;
}
// Store elements of subset A and B
int []A = new int[N];
int []B = new int[N];
int x = 0, y = 0;
for(int i = 0; i < N; i++)
{
// If element is of type A
if (partition[i] == 'A')
{
A[x++] = ((i + 1) * (i + 1));
}
// If the element is of type B
else
{
B[y++] = ((i + 1) * (i + 1));
}
}
// Print the minimum subset difference
Console.WriteLine(subsetDifference);
// Print the first subset
for(int i = 0; i < x; i++)
Console.Write(A[i] + " ");
Console.WriteLine();
// Print the second subset
for(int i = 0; i < y; i++)
Console.Write(B[i] + " ");
}
// Driver Code
public static void Main(string[] args)
{
int N = 8;
// Function Call
minimumSubsetDifference(N);
}
}
// This code is contributed by AnkitRai01
0
1 16 36 49
4 9 25 64
时间复杂度: O(N)
辅助空间: O(N)