如果我有来自1 to n
的n-r
数字,其中r
数字在两者之间缺失,那么我如何计算这些数字相加可以形成的所有可能的数字(或者以2/3/4/5/6为一组...)。
例如,假设我有5-2
号,也就是说,缺少1 2 4
和3 5
。现在,我可以形成
1 - {1}
2 - {2}
3 - {1,2}
4 - {4}
5 - {1,4}
6 - {4,2}
7 - {1,2,4}
8 - Cannot be formed
这是我需要找出的,这是从1开始的第一个数字,我不能使用给定数字的组合来形成它。一个简单的逻辑就可以了。谢谢!
发布于 2015-01-09 01:38:16
假设S[i]
是可以由数字的第一个i
组成的数字集。然后给定S[i]
,很容易构造S[i+1]
:从S[i]
开始,然后添加s+r
形式的所有数字,其中s
在S[i]
中,r
是列表中的(i+1)
-th数字。
因此,您可以迭代地构建集合s[0] = {0}, S[1],...,S[n-r]
,并且S[n-r]
包含所有可能的和。
下面是你的例子的结果:
S[0] = {0}
r = 1: S[1] = {0} union {0+1} = {0,1}
r = 2: S[2] = {0,1} union {0+2,1+2} = {0,1,2,3}
r = 4: S[3] = {0,1,2,3} union {0+4,1+4,2+4,3+4} = {0,1,2,3,4,5,6,7}
发布于 2015-01-09 04:26:02
逻辑是为每个连续的整数构建所有可能的和,从1开始。这个问题可以通过跟踪所有可能的和并只检查整数对的和来简化。伪代码(未经测试且有buggy)将如下所示:
const std::vector<unsigned> l = {1,2,4};
const unsigned sum = std::accumulate(l.begin(), l.end());
typedef std::vector<unsigned> Sum; // one possibility for a single value
typedef std::vector<Sum> Sums; // all possibilities for a single value
// the element all[i] will provide all possible subsets where the sum is equal to 'i'
std::vector<Sums> all(sum + 2); // we know that sum + 1 is impossible
// initialize with single values
for (auto i: l)
{
all[i].push_back(Vector(1, i));
}
unsigned i = 1; // ignore 0
// stop as soon as a value doesn't have any subset
while (!all[i].empty())
{
++i;
for (unsigned j = 1; i/2 > j; ++j)
{
const unsigned k = i - j;
// as i == j+k, create all the relevant combinations
for (const auto &sj: all[j])
{
for (const auto &sk: all[k])
{
all[i].push_back(sj);
all[i].back.insert(all[i].end(), sk.begin(), sk.end());
}
}
}
if (0 == (i % 2))
{
// create all the possible decompositions out of i/2
for (auto left = all[i/2].begin(); all[i/2].end() != left; ++left)
{
for (auto right = left + 1; all[i/2].end() != right; ++ right)
{
all[i].push_back(*left);
all[i].back.insert(all[i].end(), right->begin(), right->end());
}
}
}
}
需要解决的一个错误是:当相同的数字多次出现时,拒绝求和。
https://stackoverflow.com/questions/27845636
复制相似问题