给定两个整数X和S ,任务是构造一个范围为[1,X]的不同整数的序列,以使值2 K的总和等于S ,其中K是从整数开始的第一个设置位的位置。每个元素的二进制表示形式的结尾(基于0的索引)是S。
例子:
Input: X = 3, S = 4
Output: 2 3 1
Explanation:
Summation of 2K for every element in the set is as follows:
For 2, it is 2^1 = 2.
For 3, it is 2^0 = 1.
For 1, it is 2^0 = 1.
Therefore, the required sum = 2 + 1 + 1 = 4, which is equal to S.
Input: X = 1, S = 5
Output: -1
方法:可以使用贪婪方法解决问题。请按照以下步骤解决问题:
- 初始化一个变量,例如lowBit,以存储任意数量的2 K值,其中K是从每个元素的二进制表示形式开始的第一个设置位的位置。
- 将对[1,X]内所有数字的lowBit的所有值插入对V的向量中,以将数字与它们的lowBit值配对。 lowBit(X)的值可以通过log2(N&-N)+1获得。
- 以相反的顺序对向量进行排序,首先获得最大的lowBit 。
- 初始化一个数组,例如ans [] ,以存储所需的集合,并初始化一个整数,例如ansSum,以存储lowBit值的当前总和。
- 遍历向量V并执行以下步骤:
- 检查是否(ansSum + v [i] .first)<= S ,然后将v [i] .second的值添加到数组ans []并更新ansSum 。
- 如果ansSum等于给定的总和S,则从循环中断开并打印结果数组ans []作为结果。
- 如果发现ansSum不等于S,则打印“ -1” 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to calculate the lowest
// set bit of any number N
int lowBit(int N)
{
return log2(N & -N) + 1;
}
// Function to generate the sequence
// which adds up to sum on raising 2
// to the power of lowest set bit
// of all integers from the sequence
void find_set(int X, int sum)
{
// Stores the lowBit value
vector > v;
// Traverse through 1 to X and
// insert all the lowBit value
for (int i = 1; i <= X; i++) {
pair aux;
aux.first = lowBit(i);
aux.second = i;
v.push_back(aux);
}
// Sort vector in reverse manner
sort(v.rbegin(), v.rend());
bool check = false;
// Store all our set values
vector ans;
// Stores the current
// summation of lowBit
int ansSum = 0;
// Traverse vector v
for (int i = 0; i < v.size(); i++) {
// Check if ansSum+v[i].first
// is at most sum
if (ansSum + v[i].first <= sum) {
// Add to the ansSum
ansSum += v[i].first;
ans.push_back(v[i].second);
}
// If ansSum is same as the sum,
// then break from loop
if (ansSum == sum) {
check = true;
break;
}
}
// If check is false, no such
// sequence can be obtained
if (!check) {
cout << "-1";
return;
}
// Otherwise, print the sequence
for (int i = 0; i < ans.size(); i++) {
cout << ans[i] << " ";
}
}
// Driver Code
int main()
{
int X = 3, S = 4;
// Generate and print
// the required sequence
find_set(X, S);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
// User defined Pair class
class Pair {
int x;
int y;
// Constructor
public Pair(int x, int y)
{
this.x = x;
this.y = y;
}
}
// class to define user defined conparator
class Compare
{
static void compare(Pair arr[], int n)
{
// Comparator to sort the pair according to second element
Arrays.sort(arr, new Comparator() {
@Override public int compare(Pair p1, Pair p2)
{
return p1.x - p2.x;
}
});
}
}
// Driver class
class GFG
{
// Function to calculate the lowest
// set bit of any number N
static int lowBit(int N)
{
return (int)(Math.log(N & -N) / Math.log(2)) + 1;
}
// Function to generate the sequence
// which adds up to sum on raising 2
// to the power of lowest set bit
// of all integers from the sequence
static void find_set(int X, int sum)
{
// Stores the lowBit value
Pair v[] = new Pair[X];
// Traverse through 1 to X and
// insert all the lowBit value
for (int i = 0; i < X; i++)
{
Pair aux = new Pair(lowBit(i + 1), i + 1);
v[i] = aux;
}
// Sort vector in reverse manner
Compare obj = new Compare();
obj.compare(v, X);
int j = X - 1;
for(int i = 0; i < X / 2; i++)
{
Pair temp = v[i];
v[i] = v[j];
v[j] = temp;
j--;
}
boolean check = false;
// Store all our set values
Vector ans = new Vector();
// Stores the current
// summation of lowBit
int ansSum = 0;
// Traverse vector v
for (int i = 0; i < X; i++) {
// Check if ansSum+v[i].first
// is at most sum
if (ansSum + v[i].x <= sum) {
// Add to the ansSum
ansSum += v[i].x;
ans.add(v[i].y);
}
// If ansSum is same as the sum,
// then break from loop
if (ansSum == sum) {
check = true;
break;
}
}
// If check is false, no such
// sequence can be obtained
if (!check)
{
System.out.println("-1");
return;
}
// Otherwise, print the sequence
for (int i = 0; i < ans.size(); i++)
{
System.out.print(ans.get(i) + " ");
}
}
// Driver code
public static void main(String[] args)
{
int X = 3, S = 4;
// Generate and print
// the required sequence
find_set(X, S);
}
}
// This code is contributed by divyeshrabadiya07
Python3
# Python3 program for the above approach
from math import log2, ceil, floor
# Function to calculate the lowest
# set bit of any number N
def lowBit(N):
return log2(N & -N) + 1
# Function to generate the sequence
# which adds up to sum on raising 2
# to the power of lowest set bit
# of all integers from the sequence
def find_set(X, sum):
# Stores the lowBit value
v = []
# Traverse through 1 to X and
# insert all the lowBit value
for i in range(1, X + 1):
aux = [0, 0]
aux[0] = lowBit(i)
aux[1] = i
v.append(aux)
# Sort vector in reverse manner
v = sorted(v)[::-1]
check = False
# Store all our set values
ans = []
# Stores the current
# summation of lowBit
ansSum = 0
# Traverse vector v
for i in range(len(v)):
# Check if ansSum+v[i][0]
# is at most sum
if (ansSum + v[i][0] <= sum):
# Add to the ansSum
ansSum += v[i][0]
ans.append(v[i][1])
# If ansSum is same as the sum,
# then break from loop
if (ansSum == sum):
check = True
break
# If check is false, no such
# sequence can be obtained
if (not check):
print("-1")
return
# Otherwise, prthe sequence
for i in range(len(ans)):
print(ans[i], end = " ")
# Driver Code
if __name__ == '__main__':
X, S = 3, 4
# Generate and pr
# the required sequence
find_set(X, S)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to calculate the lowest
// set bit of any number N
static int lowBit(int N)
{
return (int)(Math.Log(N & -N, 2)) + 1;
}
// Function to generate the sequence
// which adds up to sum on raising 2
// to the power of lowest set bit
// of all integers from the sequence
static void find_set(int X, int sum)
{
// Stores the lowBit value
List> v = new List>();
// Traverse through 1 to X and
// insert all the lowBit value
for (int i = 1; i <= X; i++) {
Tuple aux = new Tuple(lowBit(i), i);
v.Add(aux);
}
// Sort vector in reverse manner
v.Sort();
v.Reverse();
bool check = false;
// Store all our set values
List ans = new List();
// Stores the current
// summation of lowBit
int ansSum = 0;
// Traverse vector v
for (int i = 0; i < v.Count; i++) {
// Check if ansSum+v[i].first
// is at most sum
if (ansSum + v[i].Item1 <= sum) {
// Add to the ansSum
ansSum += v[i].Item1;
ans.Add(v[i].Item2);
}
// If ansSum is same as the sum,
// then break from loop
if (ansSum == sum) {
check = true;
break;
}
}
// If check is false, no such
// sequence can be obtained
if (!check) {
Console.Write("-1");
return;
}
// Otherwise, print the sequence
for (int i = 0; i < ans.Count; i++) {
Console.Write(ans[i] + " ");
}
}
// Driver code
static void Main()
{
int X = 3, S = 4;
// Generate and print
// the required sequence
find_set(X, S);
}
}
// This code is contributed by divyesh072019
输出:
2 3 1
时间复杂度: O(X)
辅助空间: O(X)