随机数问题

随机数问题

srand函数是随机数发生器的初始化函数。原型:void srand(unsigned seed);

用法:它初始化随机种子,会提供一个种子,这个种子会对应一个随机数,如果使用相同的种子后面的rand()函数会出现一样的随机数,如: srand(1); 直接使用1来初始化种子。不过为了防止随机数每次重复,常常使用系统时间来初始化,即使用 time函数来获得系统时间,它的返回值为从 00:00:00 GMT, 1970年1月1日, 到现在所持续的秒数,然后将time_t型数据转化为(unsigned)型再传给srand函数,即: srand((unsigned) time(&t)); 还有一个经常用法,不需要定义time_t型t变量,即: srand((unsigned) time(NULL)); 直接传入一个空指针,因为你的程序中往往并不需要经过参数获得的数据。

srand()函数和rand()函数的工作过程
(1)给srand()函数提供一个种子,该种子是一个unsigned int 类型,其取值范围是0~65535. 提供的种子要在不停的变化,(3)中rand()函数才会得到不重复的随机数,time()函数就是这个种子,它会获取系统时间,而系统时间在不停的变化
(2)调用rand()函数,这个函数会根据提供给srand()函数的“种子”,返回一个随机数,取值范围在0~32767
(3)多次调用rand()函数,得到不同的随机数

rand()函数返回的随机数范围在0~32767之间,要想产生确定范围内的随机数,
如下产生1-44之间的随机数:

double range= max-min; 算出随机数的范围(0~43)
int i=rand(); //获得一个随机数
double value;
value=((double)i/(double)RAND_MAX); //获得0~1之间的一个校验值,其中
RAND_MAXstdlib.h中宏定义的一个字符常量:#define RAND_MAX 0x7FFF
其值最小为32767,最大为2147483647通常在产生随机小数时可以使用RAND_MAX
i=(int)range*value;//产生0~max-min的一个随机值
i=i+min //产生1~max的随机值

产生1-44之间的随机小数(小数点后两位):
min *= 100; //对应后边的除以100.0
max *= 100;
double range = max - min;
double random;
double value;
int i;
i = rand();
value = ((double)i /(double) RAND_MAX); // 产生0到1之间的一个校验值
i=(int) (value * range); //把校验值乘以所需要的范围,本例中是(max-min),从而产生一个0到max-min之间的值
random = (i + min)/100.0; //除以100.0可以产生两位小数

实例:

dingyi.h
#ifndef _DING_YI_H
#define _DING_YI_H

#include "stdafx.h"
#include "iostream"
using namespace std;
#define  N 100
void RedWars(double total,int person);
void RedWars1(double total,int person,double min,double max);
 Random(double min,double max);
#endif
shixian.cpp
#include "stdafx.h"
#include <ctime>      //时间函数头文件
#include <cstdlib>
#include <iomanip>
#include "conio.h" //控制台输入输出文件_getch()函数
#include "windows.h"//Sleep()函数
#include "DingYi.h"
void RedWars(double total, int person)
{
    double num[N];
    cout << "按任意键开始抢红包" << endl;
    _getch();    //按任意键继续
    srand((unsigned int)time(NULL));    //设定随机数种子,设计的随机数种子不一样,每次运行程序rand()产生的数就是不一样的

    for (int i = 0; i < person; i++)
    {
        Sleep(1000);    //让程序睡眠1秒钟(1000毫秒)
        if (i == person - 1)
            num[i] = total;
        else
        {
            num[i] = (rand() % (int)(total * 40) + 1) / 100.0;

        }
        cout << "被第" << i + 1 << "个人抢走" << num[i] << "元" << endl;
        total -= num[i];
    }
    double max = num[0];
    int   max_per = 1;
    for (int i = 1; i < person; i++)
        if (max < num[i])
        {
            max = num[i];
            max_per = i + 1;
        }
    cout << "第" << max_per << "个人是运气王" << endl;
}

double Random(double min, double max)
{
    min *= 100;
    max *= 100;
    double range = max - min;
    double random;
    double value;
    int i;
    i = rand();
    value = ((double)i /(double) RAND_MAX);  //  产生0到1之间的一个校验值
    i=(int) (value * range);        //把校验值乘以所需要的范围,本例中是(max-min),从而产生一个0到max-min之间的值
    random = (i + min)/100.0;        //把该值和最小值相加,最后产生一个落在正确范围内的随机值
    return random;
}


问题描述:

请认真阅读每道题目,并按题目要求进行作答。
大家知道微信的拼手气红包是随机金额,每个人抢到的是随机的,差别可能非常大,有的人抢到的是1分,有的抢
到的可能是几元、十几元、几十元

现要求改进该抢红包算法:结合固定金额和随机金额,可以输入总金额(tota)、总人数(um)、每个红包的最低金额
(min)和最高金额(max),固定给第一个人发1元,其它人的金额在m和max之间随机产生,这样就可以控制每个抢
到红包的,抢到的不会太少,也不会太多。

说明:金额要求支持到角分,程序运行完成之后需要根据输入打印出以下结果。
如输入  总金额10.56元,总人数5红包最小金额18元,最大金额3元
程序预期输出

抢红包结果如下:
第1个人抢到的红包金额为1.00,红包剩余金额为9562个人抢到的红包金额为221,红包剩余金额为7353个人抢到的红包金额为255,红包剩余金额为4804个人抢到的红包金额为2.22,红包剩余金额为2585个人抢到的红包金额为258,红包剩余金额为0.00
抢到红包金额最多的是5号

【答题要求】
请根据要求完成编码,提供main函数,要求考虑编码可读性、性能
void RedWars1(double total, int person, double min, double max)
{
    double num[N];  
    for (int i = 0; i < person; i++)
    {
        if (i == person - 1)
        {
            num[i] = total;
        }
        else if(i==0)
        {
            num[i] = 1;
            total -= num[i];
            cout << "第"<<i+1 << "个人抢到红包金额为:" << fixed << setprecision(2) <<num[i]<<"  " << "剩余金额为:" <<fixed<<setprecision(2)<<total << endl;
            continue;
        }
        else
        {
            num[i] = Random(min,max);
        }
        total -= num[i];
        cout << "第" << i+1 << "个人抢到红包金额为:" << num[i] << "  " << "剩余金额为:" << fixed << setprecision(2) << total << endl;
    }
    double Max = 0;
    int number;
    for (int i = 0; i < person; i++)
    {
        if (Max < num[i])
        {
            Max = num[i];
            number = i + 1;
        }
    }
    cout << "运气王是:" << number << "号" << endl;
}
main.c
// QiangHongBao.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "DingYi.h"
#include <time.h>
#include <cstdlib>
int Person;
int main()
{
    double Total, max;
    cout << "输入红包总额和抢红包人数:" << endl;
    cin >> Total >> Person;
    RedWars(Total,Person);

    double min;
    cout << "输入随机数的范围:" << endl;
    cin >> min>>max;
    srand((unsigned int)time(NULL));
    for (int i=0;i<6;i++)
    {
        cout<<Random(min, max)<<endl;
    }

    cout << "输入红包总额,抢红包人数,红包金额的最小和最大值:" << endl;
    cin >> Total >> Person >> min >> max;
    RedWars1(Total,Person,min,max);

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值