=======来吧,比较容易的一个问题,没有最优,只有更优=========
已知: 现需要产生N个随机数
要求:
1. 其总和为SUM
2. 最大值与最小值差小于MAX
3. 最小值应大于MIN
求良好的解决方法
就不要说题目好不好了,以题目定的框架讨论吧,主要是思路
3ks。
[解决办法]
/*
已知: 现需要产生N个随机数
要求:
1. 其总和为SUM
2. 最大值与最小值差小于MAX
3. 最小值应大于MIN
思路:
既然我们用 int(rand() * X) 来获得一个随机的整数
那么,int(rand() * X + E)也是一个随机整数 E为 [0,1)的实数
1、生成一堆[0, MAX-MIN)的实数 Ti
2、每个Ti都加上MIN,取整求和结果如果比SUM大,重复第1步,直到不大于SUM
3、用二分法求E,记Ti+MIN+E 取整求和为 S
(a)若S=SUM,进入第4步
(b)若E的变动区间太小,重复第1步
(c)根据S与SUM的大小比较,调整E值
4、若最大值最小值差小于MAX,得解。否则重复第1步
*/
#include <time.h>
#include <iostream>
using namespace std;
const int NUM = 50;
const int SUM = 5000;
const int MAX = 200;
const int MIN = 10;
void GetRandom(double* T, int N, int Min, int Max)
{
double Range = (double)(Max - Min);
for (int i = 0; i < N; ++i)
{
T[i] = Range * rand() / (double) RAND_MAX;
}
}
int Summary(double* T, double E, int N)
{
int Sum = 0;
for (int i = 0; i < N; ++i)
{
Sum += (int)(T[i] + E);
}
return Sum;
}
int GetRange(double* T, double E, int N)
{
double Max = T[0];
double Min = T[0];
for (int i = 1; i < N; ++i)
{
if (T[i] > Max)
{
Max = T[i];
}
if (T[i] < Min)
{
Min = T[i];
}
}
return (int)(Max + E) - (int)(Min + E);
}
void Output(double* T, double E, int N)
{
int S = 0;
double Hi = T[0];
double Lo = T[0];
for (int i = 0; i < N; ++i)
{
printf_s("%5d%c", (int)(T[i] + E), (i + 1) % 10 == 0 ? '\n' : ' ');
S += (int)(T[i] + E);
if (T[i] > Hi)
{
Hi = T[i];
}
if (T[i] < Lo)
{
Lo = T[i];
}
}
printf_s("SUM=%d, MAX=%d, MIN=%d, MAX-MIN=%d\n", S, (int)(Hi + E), (int)(Lo + E), (int)(Hi + E) - (int)(Lo + E));
}
int main()
{
srand((unsigned)time(NULL));
double* T = new double[NUM];
double E = 0.0;
int S = 0;
do
{
GetRandom(T, NUM, 0, MAX);
double Lo = 0.0;
double Hi = 1.0;
E = (double)MIN; //这里有问题,已订正
if ((S = Summary(T, E, NUM)) > SUM)
{
continue;
}
double BASE = (double)(MIN + (SUM - S) / NUM); // 这里也需要跟着更改
while (S != SUM && Hi - Lo > 0.01)
{
E = BASE + (Hi + Lo) / 2;
S = Summary(T, E, NUM);
if (S > SUM)
{
Hi = (Hi + Lo) / 2;
}
else
{
Lo = (Hi + Lo) / 2;
}
}
} while (S != SUM
[解决办法]
GetRange(T, E, NUM) >= MAX);
Output(T, E, NUM);
delete[] T;
T = NULL;
system("pause");
return 0;
}