实现一个抢红包算法
红包功能需要满足哪些具体规则呢?
1.所有人抢到的金额之和要等于红包金额,不能多也不能少。
2.每个人至少抢到1分钱。
3.要保证红包拆分的金额尽可能分布均衡,不要出现两极分化太严重的情况。
方案
每次的金额在 [0.01, 金额/人数 乘以 2) 里随机,其中金额为剩余的钱,人数为未抢红包的人数。
比如说: 10元,5个人抢
第一轮随机: [0.01, 10/5*2) 平均可以分到 2 元,有一半的概率高于两元,一半的概率低于两元,假设第一轮得到的是2元。第二轮随机: [0.01, 8/4*2) 平均分到2元。第三轮随机: [0.01, 6/3*2) 平均分到2元。第四轮随机: [0.01, 4/2*2) 平均分到2元。第五轮随机: 10 - 前四次的和。我用C++写了一个,可以参考一下。
includeincludeincludeincludeincludeincludeusing namespace std;class RedPackage {private: queue q; double totalMoney =0;public: RedPackage(double money,intcount) {intpeopleNum = count; double rawMoney = money;for(inti =0; i < count -1; ++i) { double avg = money / peopleNum; double m = RandRangeF(0.01, avg *2); m = (int)(m *100) /100.0; money -= m; --peopleNum; q.push(m); totalMoney += m; } q.push(money); totalMoney += money; assert(totalMoney == rawMoney); }intRandRange(intm,intn)const{return(rand() / RAND_MAX) * (n - m) + m; } double RandRangeF(double m, double n)const{ double ratio = static_cast(rand()) / RAND_MAX;returnratio * (n - m) + m; } void Display() {inti =0; while (!q.empty()) { double m = q.front(); q.pop(); cout <<"第"<< ++i <<"人抢到的红包金额是: "<< m << endl; } }};intmain(intargc, charconst* argv[]){ unsigned seed = time(0); srand(seed); RedPackage red(100,5); red.Display();return0;}当然一些数据的合法性检查也可以校验一下,比如说 1 元,发了11个人等等。
...