我被要求生成3次幂集{1,3,9,27,81,....}的子集,然后按其总和的递增顺序排列子集,例如{{},{ 1} ,, {3},{1,3},{9},{1,9},{3,9},{1,3,9},..........}。最后,当用户输入n时,我们需要打印第n个子集,例如,如果n = 4,则解是第三个子集{1,3}。 n的范围基本上非常大。
我怀疑是:
答案 0 :(得分:2)
对于这个问题,3的幂或2的幂是相同的,但是更容易看到具有2的幂的解。见序列:
因此,解决方案是以二进制计数然后解释基数为3的给定数字。例如:
因此,对于给定的n
,将其转换为二进制,然后再转换为三元组。
这是代码:
private static String calc(int n) {
String binary = Integer.toString(n - 1, 2);
String reverse = new StringBuilder(binary).reverse().toString();
StringBuilder sb = new StringBuilder();
sb.append("{");
for (int i = 0; i < reverse.length(); i++) {
if(reverse.charAt(i) == '1') {
sb.append(BigInteger.valueOf(3).pow(i)).append(" ");
}
}
//remove last space
if(sb.length() != 1) { sb.deleteCharAt(sb.length() -1); }
sb.append("}");
return sb.toString();
}
测试:
for(int i = 1; i<=10; i++) {
System.out.println(calc(i));
}
结果:
{}
{1}
{3}
{1 3}
{9}
{1 9}
{3 9}
{1 3 9}
{27}
{1 27}
答案 1 :(得分:0)
答案 2 :(得分:0)
除了蛮力外,还有其他方法。
是的。尝试生成有序的集合序列。我们可以证明这将使用归纳法。
最小总和为{}
假设您已经订购了包含N的数字的所有子集。
要生成包含N的所有子集,只需将N添加到步骤2中的每个集合(按相同顺序)
这将起作用,因为以下情况属实 - 3 ^ n&gt; 3 ^ n-1 + 3 ^ n-2 ....例如,子集sum({3 ^ n})大于仅包含3 ^ n-1和更小元素的所有子集的总和。
示例强>
答案 3 :(得分:0)
我们只需要将给定的'n'转换为二进制,然后提高 3 ^ i 的幂(仅当第i位为 setbit ),因为只有setbit会贡献子集。
这将因以下条件而起作用:(3 ^ n> 3 ^ n-1 + 3 ^ n-2) 例如:3 ^ 2> 3 ^ 1 + 3 ^ 0
现在的代码:
void decimalToBinary(long int n)
{
int binaryNum[32]; // array to store binary number
int i = 0; // counter for binary array
while (n > 0) { // storing remainder in binary array
binaryNum[i] = n % 2;
n = n / 2;
i++;
}
for (int j = 0; j <i; j++)
{
if(binarray[j]==1)
cout<<binpower(3,j)<<" "; //must be binary exponentiation
}
}
输入:6
输出:3 9
答案 4 :(得分:0)
很容易看出,如果以n的二进制表示形式设置了第i位,则可以通过打印集合S的第i个元素来生成子集,如果不设置该位,则不打印任何内容。 / p>