模拟微信红包

要求:输入人数和金额总数(人数1-50,金额数不大于200,同时保证每个人至少0.01元),打印每个红包的金额数,要求金额分布要相对均匀,不允许大金额的红包集中在同一个区域,不允许金额数目都递增或递减的规律变化,也不允许有太大的差距,如199。2 和0.8….

代码实现过程:利用srand()生成伪随机数的种子,考虑到每次运行的红包分布都要不同,所以使用时间作为 种子,即srand((unsigned int)time(0));
在代码运行过程中rand()生成0-32767的随机数。

由于每个人获得的金额最多为三位数,同时为带小数的数值,因此,rand()生成的随机数需要除以100.0会更符合我们的要求。

又由于金额分布需要相对均匀,于是便想到了平均数,由于不允许相同,便利用平均数(剩下的钱除以剩下的人),结合题目给出的金额要求限定了一个区间。只要随机数除以100.0之后的值在区间内,即作数!否则,忽略这个随机数,不计入红包金额中。

p = rand() / 100.0;
p >= 0.01&&p < (m / n) * 2 && p<m-(n-1)*0.01

同时,在测试运行时会发现,在5个人,金额总数为0.06的情况下,总会是最后一个人拿到0.02元,也就是不符合随机分配的要求;以及在5个人,0.05元的情况下,经常会出现打印时只能打印2个人,3个人的红包金额数,主要是由于在后面的随机数中,要达到我说限定的要求的概率太小了。因此,我把这两种情况分离出来进行了讨论。

解决这个问题之后,代码就不难了。
下面贴上完整的代码

#include <iostream>
#include <stdlib.h> //srand/rand函数
#include <time.h>   //time函数
#include<iomanip>
using namespace std;
int main()
{
    int n, imax = 1;;
    double m,p,max=0;
    while (1)
    {
        cout << "请输入人数n[1,50]以及金额m[0.01,200]: "; 
        cin >> n >> m;
        if (m >= (0.01*n)&&m<=200&&n<=50&&n>=1)
            break;
     }
    srand((unsigned int)time(0));
    cout << endl << "每个人的红包金额为:" << endl;
    if (n == 1)
        cout << m << endl;
    else if (m == 0.01*(n + 1))
    {
        int index = rand() % n + 1;
        for(int i=1;i<=n;i++)
            if(i==index)
                cout<<"第"<<i<<"个人抢到的红包金额为:0.02元" << endl;
            else
                cout << "第" << i << "个人抢到的红包金额为:0.01元" << endl;
    }
    else if(m==0.01*n)
        for (int i = 1; i <= n; i++)
                cout << "第" << i << "个人抢到的红包金额为:0.01元" << endl;
    else
    {
        int c = n;
        for (int i=0;n >1;)
        {
            p = rand() / 100.0;
            if (p >= 0.01&&p < (m / n) * 2 && p<m-(n-1)*0.01)//为均衡几率,以与平均数相关的数据来做阈值,同时,为了防止数据呈前大后小的情况,*2
            {
                i++;
                cout << "第"<<i<<"个人抢到的红包金额为:"<<p<<"元" << endl;
                m = m - p;
                n--;
                if (p > max)
                {
                    max = p;
                    imax = i;
                }
            }
        }
        cout << "第" << c << "个人抢到的红包金额为:" << m << "元" << endl;
        if (m > max)
        {
            max = m;
            imax = c;
        }
        cout<< "第" << imax << "个人是手气王\n抢到的红包金额为:" << max << "元" << endl;
    }
    return 0;
}

仍旧存在的问题:金额为0.07,5个人,不会有0.03元的红包

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值