如果我有n-r
数字,从1到n
,其中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中的第一个数字。一个简单的逻辑就可以了。谢谢!
集合
开始set
和你的第一个数字的所有可能的和(所以如果你的第一个数字是1,那么你的set
包含1和0)set
包含0、1、2和3)该集包含所有可能的数字。您需要遍历集,找到第一个间隙。即使你的集合中有负数,这也会起作用。
我知道你说过你只是想了解逻辑,但如果你想在下面看到一个解决方案鼠标:
<代码>设置
如果您试图使用STL算法实现set
中的间隙搜索,我发现这有点困难。问题是您需要将迭代器的增量与其比较分开。
例如,这将不起作用:
<罢工>
因为如果所有数字都是连续的,则prev(i)1是集合中的最后一个值。
此选项将起作用:
i = foo.begin();
while (i != prev(foo.end()) && *i + 1 == *next(i)){
++i;
}
cout << "First number that cannot be formed " << *i + 1 << endl;
但这假设您的集始终包含至少0。
让S[i]
是可以由您的数字的第一个i
形成的数字集。然后给定S[i]
,很容易构造S[i 1]
:从S[i]
开始,然后添加s r
形式的所有数字,其中s
在S[i]
中,r
是(i 1)
-列表中的第10个数字。
因此,您可以迭代地构建集s[0]={0},s[1],。。。,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}
逻辑是从1开始为每个连续整数构建所有可能的和。通过跟踪所有可能的和并只检查整数对的和,可以简化该问题。伪代码(未测试和有缺陷)看起来像:
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());
}
}
}
}
需要解决的错误之一是:拒绝同一数字多次出现的总和。
我试图从表示数字的int数组生成所有可能的数字。 例如,我得到以下结果。 例如,arr=new int[]{1,2,3},我得到以下结果。 1 2 3 11 21 31 12 22 32 13 23 33 111 211 311 121 221 321 131 231 331 112 212 312 122 222 322 132 232 332 113 213 313 123 223 323 1
问题内容: 我正在为Android开发一个数学应用程序。在这些字段之一中,用户可以输入一个整数(无数字且大于0)。这个想法是获得所有可能的和,使之成为整数,而不加倍(在这种情况下为4 + 1 == 1 + 4)。唯一已知的是此int。 例如: 假设用户输入4,我希望该应用返回: 4 3 + 1 2 + 2 2 + 1 + 1 1 + 1 + 1 + 1 显然4 == 4,所以也应该加上。关于我应该
我遇到的问题如下: 对于给定的不同十进制数字数组(0,1,2,3...,8,9)编写一个递归函数,返回由给定数字组成的所有自然数的总和。例如,对于数组{1,2},您将获得12 21 2 1 = 36 我想的是如果你有一个数组1,2,3 您可以将最后一个数字“放在一边”,并将剩下的较小的一组按如下方式排列: 1 2 3 2 1 3 2 3 1 3 3 这将是10*[perm(1,2)]3*(重复次数
根据这个帖子,我们可以通过下面的代码得到一个数的所有约数。 例如,数字的除数是。 在搜索了一些相关的帖子后,我没有找到任何好的解决方案。有什么有效的方法来实现这一点吗? 我的解决方案: 通过这个解求出给定数的所有素因子 得到这些基本因子的所有可能组合 然而,这似乎不是一个好办法。
问题内容: 我有从0到8的数字。我想结果是这些数字的所有可能集合,每个集合都应使用所有数字,每个数字在集合中只能出现一次。 我希望看到用PHP制作的解决方案可以打印出结果。或者,至少,我希望在组合理论上有所收获,因为我早已忘记了它。计算多少排列的公式是什么? 示例集: 0-1-2-3-4-5-6-7-8 0-1-2-3-4-5-6-8-7 0-1-2-3-4-5-8-6-7 0-1-2-3-4-8
我有一个问题困扰着我的大脑。让我们假设变量I存储一个序列,变量II存储另一个序列,变量III存储另一个序列。变量1将表示数字1、下一个2和下一个3;然后我有另一个关键变量,具有这3个序列的随机字符。考虑到这一事实,我可以很容易地将这个关键变量的字符翻译成相应的数字。在示例中,,than,也就是说,x='123',因为A或B或C=1,依此类推。 现在是复杂的部分: 当关键变量x被转换为数字时,每个字