构造具有最大差小于 d 的 X 个子序列的数组
给定两个数字 X 和 d,其中 X 表示非空子序列的数量,d 表示差异。输出一个大小为 N 的数组,其非空子序列等于 X,其中每个子序列的最大元素和最小元素之间的差应小于 d。
Constraints:
1 ≤ N ≤ 500
1 ≤ X ≤ 109
例子:
Input : X = 10, d = 5
Output : 5 50 7 15 6 100
"10" desired subsequences are: [5], [50], [7],
[15], [6], [100], [5, 7], [5, 6], [7, 6],
[5, 7, 6].
Input : X = 4, d = 10
Output : 10 100 1000 10000
"4" desired subsequences are: [10], [100],
[1000], [10000].
方法:可以清楚地看到,如果 d = 5,则数组 [1, 7] 将只有 2 个所需的子序列([1] 和 [7] 而不是 [1, 7])。因此,类似地,如果我们在该数组中添加许多 1 和许多 7,那么也不会接受同时具有 1 和 7 的子序列。因此,差异大于 d 的元素将始终形成不相交的集合。例如在 [1, 5, 9, 9, 12, 13] 中,如果 d = 2,则有 4 个不相交的集合 [1], [5], [9, 9], [12, 13]。
大小为 N 的数组中非空子序列的总数等于 -1。因此,我们只需要找到子序列总数恰好小于或等于 X 的不相交集的长度,并输出该不相交集的元素。如果它不等于 X,则必须对缩减的 X 执行相同的步骤以找到下一个不相交的集合,直到 X 变为 0。为了使所有集合不相交,一种方法是将第一个数组元素作为 1,然后在其中添加 1第一个不相交集等于该不相交集的长度,然后将“d”添加到前一个不相交集中的元素以形成另一个不相交集,依此类推。
For e.g: X = 25, d = 100
1st disjoint set will have 4 elements as it has 15 subsequences. So 1st disjoint set will be { 1, 1, 1, 1 }.
Now X becomes 10 and thus second disjoint set will contain only 3 elements. So 2nd. disjoint will be { 101, 101, 101 } (by adding 100 in 1 to make it disjoint from 1st set). Now X becomes 3 and thus final disjoint set will contain two elements and 3rd disjoint set will be { 201, 201 } (by again adding 100 in 101 to make it disjoint from both the previous sets).
Final Output will be [1, 1, 1, 1, 101, 101, 101, 201, 201].
下面是上述方法的实现。
C++
// C++ Program to output an array having exactly X
// subsequences where difference between maximum
// and minimum element of each subsequence is less
// than d
#include
using namespace std;
// This function outputs the desired array.
void printArray(int X, int d, int first_ele)
{
// Iterate till all the disjoint sets are found.
while (X > 0) {
// count_ele the elements in one disjoint
// set. pow_of_two will keep all the
// powers of twos.
int count_ele = 0, pow_of_two = 2;
// Iterate to know the maximum length of
// disjoint set by checking whether X is
// greater than the total number of
// possible not empty sequences of that
// disjoint set.
while (X - pow_of_two + 1 >= 0) {
count_ele++;
pow_of_two *= 2;
}
// now deleting the total subsequences of
// the maximum length disjoint set from X.
X = X - (pow_of_two / 2) + 1;
// outputting the disjoint set having equal
// elements.
for (int j = 0; j < count_ele; j++)
cout << first_ele << " ";
// by adding d, it makes another disjoint
// set of equal elements.
first_ele += d;
}
}
// Driver Code
int main()
{
int d = 100, X = 25;
printArray(X, d, 1);
return 0;
}
Java
// Java Program to output
// an array having exactly
// X subsequences where
// difference between maximum
// and minimum element of
// each subsequence is less
// than d
import java.io.*;
class GFG
{
// This function outputs
// the desired array.
static void printArray(int X, int d,
int first_ele)
{
// Iterate till all the
// disjoint sets are found.
while (X > 0)
{
// count_ele the elements
// in one disjoint set.
// pow_of_two will keep
// all the powers of twos.
int count_ele = 0,
pow_of_two = 2;
// Iterate to know the
// maximum length of
// disjoint set by checking
// whether X is greater than
// the total number of possible
// not empty sequences of that
// disjoint set.
while (X - pow_of_two + 1 >= 0)
{
count_ele++;
pow_of_two *= 2;
}
// now deleting the total
// subsequences of the maximum
// length disjoint set from X.
X = X - (pow_of_two / 2) + 1;
// outputting the disjoint
// set having equal elements.
for (int j = 0;
j < count_ele; j++)
System.out.print(first_ele + " ");
// by adding d, it makes
// another disjoint set
// of equal elements.
first_ele += d;
}
}
// Driver Code
public static void main (String[] args)
{
int d = 100, X = 25;
printArray(X, d, 1);
}
}
// This code is contributed
// by anuj_67.
Python3
# Python 3 Program to output an array having
# exactly X subsequences where difference
# between maximum and minimum element of each
# subsequence is less than d
# This function outputs the desired array.
def printArray(X, d, first_ele):
# Iterate till all the disjoint
# sets are found.
while (X > 0):
# count_ele the elements in one
# disjoint set. pow_of_two will
# keep all the powers of twos.
count_ele, pow_of_two = 0, 2
# Iterate to know the maximum length of
# disjoint set by checking whether X is
# greater than the total number of
# possible not empty sequences of that
# disjoint set.
while (X - pow_of_two + 1 >= 0):
count_ele += 1
pow_of_two *= 2
# now deleting the total subsequences of
# the maximum length disjoint set from X.
X = X - (pow_of_two / 2) + 1
# outputting the disjoint set having
# equal elements.
for j in range(count_ele):
print(first_ele, end = " ")
# by adding d, it makes another
# disjoint set of equal elements.
first_ele += d
# Driver Code
if __name__ == '__main__':
d, X = 100, 25
printArray(X, d, 1)
# This code is contributed by PrinciRaj19992
C#
// C# Program to output
// an array having exactly
// X subsequences where
// difference between maximum
// and minimum element of
// each subsequence is less
// than d
using System;
class GFG
{
// This function outputs
// the desired array.
static void printArray(int X, int d,
int first_ele)
{
// Iterate till all the
// disjoint sets are found.
while (X > 0)
{
// count_ele the elements
// in one disjoint set.
// pow_of_two will keep
// all the powers of twos.
int count_ele = 0,
pow_of_two = 2;
// Iterate to know the
// maximum length of
// disjoint set by checking
// whether X is greater than
// the total number of possible
// not empty sequences of that
// disjoint set.
while (X - pow_of_two + 1 >= 0)
{
count_ele++;
pow_of_two *= 2;
}
// now deleting the total
// subsequences of the maximum
// length disjoint set from X.
X = X - (pow_of_two / 2) + 1;
// outputting the disjoint
// set having equal elements.
for (int j = 0;
j < count_ele; j++)
Console.Write(first_ele + " ");
// by adding d, it makes
// another disjoint set
// of equal elements.
first_ele += d;
}
}
// Driver Code
public static void Main ()
{
int d = 100, X = 25;
printArray(X, d, 1);
}
}
// This code is contributed
// by anuj_67.
PHP
0)
{
// count_ele the elements in
// one disjoint set. pow_of_two
// will keep all the powers of twos.
$count_ele = 0;
$pow_of_two = 2;
// Iterate to know the maximum
// length of disjoint set by
// checking whether X is greater
// than the total number of possible
// not empty sequences of that
// disjoint set.
while ($X - $pow_of_two + 1 >= 0)
{
$count_ele++;
$pow_of_two *= 2;
}
// now deleting the total subsequences of
// the maximum length disjoint set from X.
$X = $X - ($pow_of_two / 2) + 1;
// outputting the disjoint set
// having equal elements.
for ($j = 0; $j < $count_ele; $j++)
echo $first_ele , " ";
// by adding d, it makes another
// disjoint set of equal elements.
$first_ele += $d;
}
}
// Driver Code
$d = 100;
$X = 25;
printArray($X, $d, 1);
// This code is contributed by ajit
?>
Javascript
1 1 1 1 101 101 101 201 201