随机生成和为S的N个正整数——投影法
随机生成和为S的N个正整数有很多种解法。下面讲解一种比较高效且比较有趣味性的解法——投影法。
以生成和为20的4个数为例,可以先生成随机生成0到20之间的三个数字再排序,假设得到了4,7,18。然后在X-Y数轴上画出这三个数,如下图:
然后将这些数值投影到Y轴上,可得下图:
由图很容易看出AB,BC,CD,DE这四段的长度和肯定为20。因此AB,BC,CD,DE这四段的长度即和为20的4个数,这4个数分别为4,3,11,2。
这种方法只要随机生成N - 1个小于S的不同数字,排序后计算两两差值就可以得到和为S的N个正整数,因此效率还是比较高的。下面给出完整代码(随机生成N - 1个不同数可以参考《STL系列十一随机三趣题——随机重排,文件中随机取一行,生成N个随机数》):
- #include <cstdio>
- #include <ctime>
- #include <set>
- #include <algorithm>
- using namespace std;
- //在[s, e)区间上随机取n个数并存放到a[]中
- void GetRandomNum(int *a, int n, int s, int e)
- {
- std::set<int> set_a;
- srand(time(NULL));
- for (int i = e - n; i < e; i++)
- {
- int num = (rand() % i) + s;
- if (set_a.find(num) == set_a.end())
- set_a.insert(num);
- else
- set_a.insert(i);
- }
- i = 0;
- std::set<int>::iterator pos;
- for (pos = set_a.begin(); pos != set_a.end(); pos++)
- a[i++] = *pos;
- }
- int main()
- {
- const int NSUM = 20;
- const int NCOUNT = 4;
- printf(" 生成和为%d的%d个数 \n", NSUM, NCOUNT);
- printf("--- by MoreWindows( http://blog.csdn.net/MoreWindows ) ---\n\n");
- int a[NCOUNT];
- GetRandNumberInRange(a, NCOUNT - 1, 0, NSUM);
- sort(a, a + NCOUNT - 1);
- a[NCOUNT - 1] = NSUM;
- printf(" 已经生成和为%d的%d个数: \n", NSUM, NCOUNT);
- printf("%d ", a[0]);
- for (int i = 1; i < NCOUNT; i++)
- printf("%d ", a[i] - a[i - 1]);
- putchar('\n');
- return 0;
- }
相关推荐
在编程领域,生成1到N的不重复随机数是一个常见的需求,这在各种场景中都有应用,例如模拟抽奖、创建随机测试数据或者在游戏中分配资源等。这个任务涉及到两个主要的知识点:随机数生成和数组去重。 首先,我们来...
- **乘积取中法**:选择两个初始随机数 \(x_0\) 和 \(x_1\),然后使用递推公式 \(x_{n+2} = [x_{n+1}x_n / 10^s] \mod 10^{2s}\) 生成新的随机数。与平方取中法相比,乘积取中法在随机数列长度和均匀性方面有所改善...
- 生成N个100以内的随机正整数并存入数组。 2. **显示数组**: - 输出数组s[]的初始数据。 3. **查找最大值与最小值**: - 遍历数组,找到最大值和最小值。 4. **排序数组**: - 对数组s[]进行降序排序。 5. **复制...
4. 反转输出正整数 - `input()`函数用于接收用户输入,`eval()`函数则可以将字符串转换为对应的数值类型。`s[::-1]`表示字符串的反向切片,可以实现字符串的反转。`print(eval(s[::-1]))`将反转后的字符串转换为...
快速排序的平均时间复杂度为O(n log n),最坏情况为O(n^2)。 #### 四、简单选择排序(堆排序) **定义:** 简单选择排序在这里实际上指的是堆排序。堆排序是一种基于比较的排序技术,它使用二叉堆(通常是最大堆)...
- `get_S()`方法生成特殊字符(ASCII码值33到46或58到64或91到96或123到126之间的随机字符,这部分在示例中未使用)。 `getpwd`方法通过`rd.nextInt()`选择相应的字符类型,并将生成的字符添加到结果字符串。对于每...
第2行有N个用空格隔开的正整数,为所产生的随机数。 输出格式 输出也是2行,第1行为1个正整数M,表示不相同的随机数的个数。第2行为M个用空格隔开的正整数,为从小到大排好序的不相同的随机数。 p.s.c#实现,输出一...
输入一个正整数n (1<n),再输入n 个整数,将最小值与第一个数交换,最大值与最后一个数交换,然后输出交换后的n 个数。 (25)抓住肇事者 一辆卡车违反交通规则,撞人后逃跑。现场共有三个目击者,但都没有记住车号...
Pell方程的解通常由无穷序列构成,而"Pellm"函数似乎提供了一种获取这个序列中前n个正整数解的方法。 "Pell.m"是这个功能的核心代码,很可能包含了递归或迭代算法来生成这些解。在MATLAB编程中,这样的实现可能涉及...
- **解析**:随机生成10个1~100的正整数,使用循环结构计算这些数的最大值、最小值和平均值。 #### 35. 将元素插入已排序的一维数组 - **知识点**:数组操作,排序 - **解析**:遍历数组a(),找到合适的插入位置,...
1. **定义**:如果\(m > 1\),\((a, m) = 1\)(即\(a\)与\(m\)互质),那么使得同余式\(a^y \equiv 1 (\mod m)\)成立的最小正整数\(y\)被称为\(a\)模\(m\)的次数。如果\(y = \varphi(m)\),其中\(\varphi(m)\)是欧拉...
通过随机生成三个整数 a、b 和 c,计算其最大公约数和最小公倍数。 9. 费马大定理 知识点:数学函数、理论基础 本题目考察了数学函数的应用和理论基础。费马大定理是数论领域的一个重要定理,描述了 n>2 时不存在...
伪随机数生成器的核心是通过某种算法将上一个数(或者初始值)转换为下一个数。最常见的生成算法之一是线性同余法,其公式可以表示为: \[ X_{n+1} = (aX_n + c) \mod m \] 其中: - \( X_n \) 表示当前的随机数;...
2. **计算n和φ(n)**:n=p*q,φ(n)=(p-1)*(q-1),其中φ(n)是欧拉函数值,对于素数p和q,它表示小于n且与n互质的正整数个数。在代码中,φ(n)没有直接表示,但e的选取依赖于它。 3. **选择公钥e**:公钥e是与φ(n)...
其中,`x` 是一向量,`n` 是正整数。 四、信号常见高级运算 信号高级运算是指对信号进行的高级操作,包括相关函数、差分方程等。 1. 相关函数(Correlation Function) 相关函数是指计算两个信号之间的相关性。 ...
- 计算φ(n)=(p-1)*(q-1),φ(n)是欧拉函数,表示小于n且与n互质的正整数个数。 - 选择一个与φ(n)互质的整数e,通常e取为一个相对小的素数,如65537。 - 解决模逆元问题找到d,使得(e*d) % φ(n) = 1。d是私钥,...
题目要求给定一个正整数`N`,输出`N`中所有数位上的最小数字。 - **解析:** - 方法1:将整数转换成字符串,然后使用循环遍历每个字符,并将其转换回整数,最后使用`min()`函数找到最小值。 - 方法2:直接将整数...
3. **阶n**:基点G的阶是指可以生成曲线上所有点的最小正整数倍数,即`[G]n = O`,其中O表示无穷远点。 4. **私钥d**:ECC中的私钥是一个随机选取的整数,满足`1 < d < n`,用于进行解密和签名。 5. **公钥Q**:...
在线性复杂度的定义中,如果有一个周期为N的序列s,线性复杂度是指最小的正整数l,使得存在一个次数不超过l-1的非零多项式g(x),使得序列s可以通过g(x)的线性组合来表示,即g(x)乘以序列s等于零序列。从线性反馈移位...
Rs编码的核心原理基于伽罗华域GF(p^n)上的多项式运算,其中p为素数,n为正整数。在Rs编码中,数据被表示为GF(p^n)中的元素。编码过程分为两个主要步骤:编码生成和编码校验。首先,选择一组生成多项式,通过这个生成...