从另外给定的数字形成所有可能的数字 [英] All possible numbers formed from addition of given digits
问题描述
如果我有 NR
的数字,从 1到n
,其中研究
号之间,我又如何能计算,可以从另外这些数字来形成所有可能的号码(无论是在2/3/4/5/6组...)缺少研究。
If I have n-r
numbers, from 1 to n
where r
numbers are missing in between, then how can I calculate all possible numbers that can be formed from addition of these numbers (either in groups of 2/3/4/5/6...).
举例来说,可以说我有 5-2
号,
也就是说, 1 2 4
和 3.5
失踪。现在,我可以形成
For example, lets say I have 5-2
numbers,
that is, 1 2 4
and 3 5
are missing. Now, I can form
1 - {1}
2 - {2}
3 - {1,2}
4 - {4}
5 - {1,4}
6 - {4,2}
7 - {1,2,4}
8 - Cannot be formed
这是我需要找出,也就是从1,我不能形成使用给定的数字组合的第一个数字。一个简单的逻辑将做精。谢谢!
This is I need to find out, that is the first number from 1 which I cannot form using the combination of the given digits. A simple logic would do fine. Thanks!
推荐答案
对于输入设置
s或多集
取值只包含正整数,叶夫根Kluev的解决方案是的 O(2N)的,[我的其他解决方案]是的 O(nlogn)的。
For input set
s or multiset
s which only contain positive integers, Evgeny Kluev's Solution is O(2n), [my other solution] is O(nlogn).
对于一个给定的输入号
■您可以找到unformable数如下:
For a given input number
s you can find the unformable number as follows:
- 收集
号
到int_log [I]
,其中I = INT元素(LOG2 (
元素))
- 找到
S []
这是在preFIX金额int_log []
- 第一unformable数为
S [X] + 1
,其中int_log [X + 1]
不包含元素小于或等于S [X] + 1
- Collect elements of
number
intoint_log[i]
wherei = int(log2(
element))
- Find
S[]
which is the prefix sum ofint_log[]
- The first unformable number is
S[x] + 1
whereint_log[x + 1]
contains no element less than or equal toS[x] + 1
有关证明,在范围内的所有号码[0, S [I]
] 的可以通过子集来形成 int_log
小于2 I-1 看到:<一href="http://math.stackexchange.com/questions/1099359/0-sum-re$p$psentable-by-numbers-in-a-set">http://math.stackexchange.com/questions/1099359/0-sum-re$p$psentable-by-numbers-in-a-set
For a proof that all numbers in the range [0, S[i]
] can be formed by subset of int_log
smaller than 2i-1 see: http://math.stackexchange.com/questions/1099359/0-sum-representable-by-numbers-in-a-set
set<int> numbers{ 1, 2, 5, 6, 7 };
unordered_multimap<unsigned long, decltype(numbers)::key_type> int_log;
for (auto& value : numbers){
auto key = decltype(int_log)::key_type{};
_BitScanReverse(&key, value); //If using gcc you'll need to use __builtin_clz here
int_log.insert(make_pair(key, value));
}
auto result = decltype(numbers)::key_type{}; // Because we only ever need to look at the previous prefix sum value we'll use previousSum instead of a S[] here
auto sum = decltype(numbers)::key_type{};
auto i = decltype(int_log)::key_type{};
auto smallest = decltype(numbers)::key_type{};
do{
result = sum;
smallest = 2 << i;
for (auto range = int_log.equal_range(i); range.first != range.second; ++range.first){
const auto current = range.first->second;
sum += current;
smallest = min(smallest, current);
}
++i;
} while (result >= smallest - 1);
cout << "First number that cannot be formed: " << result + 1 << endl;
这篇关于从另外给定的数字形成所有可能的数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!