从另外给定的数字形成所有可能的数字 [英] All possible numbers formed from addition of given digits

查看:146
本文介绍了从另外给定的数字形成所有可能的数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有 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 sets or multisets which only contain positive integers, Evgeny Kluev's Solution is O(2n), [my other solution] is O(nlogn).

对于一个给定的输入■您可以找到unformable数如下:

For a given input numbers you can find the unformable number as follows:

  1. 收集 int_log [I] ,其中 I = INT元素(LOG2 (元素))
  2. 找到 S [] 这是在preFIX金额 int_log []
  3. 第一unformable数为 S [X] + 1 ,其中 int_log [X + 1] 不包含元素小于或等于 S [X] + 1
  1. Collect elements of number into int_log[i] where i = int(log2(element))
  2. Find S[] which is the prefix sum of int_log[]
  3. The first unformable number is S[x] + 1 where int_log[x + 1] contains no element less than or equal to S[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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆