随机生成和为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个正整数。
#include<cstdio>
#include<ctime>
#include<set>
#include<algorithm>
usingnamespace std;
//在[s, e)区间上随机取n个不同的数并存放到a[]中
void GetRandomNum(int *a, intn, ints, inte)
{
set<int> set_a;
srand(time(0));
for (int i = 0; i < n; i++)
{
int num = (rand() % (e-s)) + s;
if (set_a.find(num) == set_a.end())
set_a.insert(num);
else
i--;
}
int i = 0;
set<int>::iterator pos;
for (pos = set_a.begin(); pos != set_a.end(); pos++)
a[i++] = *pos;
}
int main()
{
constint NSUM = 20;
constint NCOUNT = 4;
printf("生成和为%d的%d个数 \n", NSUM, NCOUNT);
int a[NCOUNT];
GetRandomNum(a, NCOUNT - 1, 10, 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;
}
n个骰子的点数
#include<stdio.h>
double * func(intn, intmaxValue)
{
if (n< = 0 || maxValue <= 0)
returnNULL;
int size = maxValue * n + 1;
//用于存放和出现的次数
int * sumArray = (int *)malloc(size * sizeof(int));
//初始化数组
for (int i = 0; i < size; i++)
{
sumArray[i] = 0;
}
//加入第一个骰子
for (int i = 1; i <= maxValue; i++)
{
sumArray[i] = 1;
}
//逐个加入骰子
for (int i = 2; i <= n; i++)
{
for (int j = i * maxValue; j >= i - 1; j--)
{
sumArray[j] = 0;
for (int k = 1; k <= maxValue; k++)
{
if (j - k <= i - 2)
break;
sumArray[j] += sumArray[j - k];
}
}
}
//用于存放和出现的概率
double * probabilitiesArray = (double *)malloc((size + 1) * sizeof(double));
//和出现的总次数,可以通过求sumArray数组的和得到,也可以通过排列数得到
int sum = 1;
for (int i = 0; i < n; i++)
sum *= maxValue;
for (int i = 0; i < size; i++)
{
/*
double除以int得double,int除以double也得double,(double)sumArray[i]/sum,
C会先将sumArray[i]转换成double,然后再除以sum,得到的是double,故小数部分不会丢失,
如果改成(double)(sumArray[i]/sum)虽然结果被转换成了double,但转换之前的结果是int,
小数部分已经丢失了
*/
probabilitiesArray[i] = (double)sumArray[i] / sum;
}
free(sumArray);
probabilitiesArray[size] = -1;
return probabilitiesArray;
}
int main()
{
double * result = func(3, 6);
for (int i = 1;; i++)
{
if (result[i] == -1)
break;
printf("%d,%f\n", i, result[i]);
}
free(result);
}
maxValue用于设置一个骰子的面数,当然,默认情况下一个骰子有6面,为了使函数更具通用性,这里允许设置骰子的面数
求1+2+3+4+....+n
#include<stdio.h>
//定义一个函数指针
typedefint(*fun)(int);
int method1(intn)
{
return 0;
}
int method2(intn)
{
fun f[2] = { method1, method2 };
return f[!!n](n-1) + n;
}
int main()
{
int result = method2(5);
printf("%d", result);
}
#include<iostream>
usingnamespace std;
classTemp
{
public:
Temp(){ ++n; sum += n; }
staticvoid Reset(){ n = 0; sum = 0; }
staticint GetSum(){ return sum; }
private:
staticint n;
staticint sum;
};
int method(intn)
{
Temp::Reset();
Temp *a = newTemp[n];
delete[]a;
a = NULL;
returnTemp::GetSum();
}
void main()
{
int sum = method(5);
cout<< sum << endl;
}
class SuperClass{
public SuperClass(){
System.out.println("SuperClass构造函数被调用");
}
}
publicclass Test {
publicstaticvoid main(String[]args){
SuperClass[]sup = new SuperClass[5];
}
}
#include<iostream>
usingnamespace std;
classA;
A * Array[2];
classA
{
public:
virtualint sum(intn){ return 0; }
};
classB :publicA
{
public:
int sum(intn)
{
return Array[!!n]->sum(n - 1) + n;
}
};
int method(intn)
{
A a;
B b;
Array[0] =& a;
Array[1] =& b;
int value = Array[1]->sum(n);
return value;
}
void main()
{
int sum = method(5);
cout<< sum << endl;
}
求素数(质数)