鱼C论坛

 找回密码
 立即注册
查看: 10366|回复: 64

[技术交流] Python:每日一题 96(答题领鱼币)

[复制链接]
发表于 2017-9-8 23:15:48 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我们都知道微信红包,把一个红包随机分成n份,每人拿到的钱数不尽相同。
现在模拟这个算法,把100块钱,随机分成10份,为了简化每个人的钱数都是整数。
例如:
7
1
9
11
3
13
10
11
2
9
24

我的解法:
游客,如果您要查看本帖隐藏内容请回复

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-8 23:47:16 | 显示全部楼层
from random import randint
n=100
k=10
while n:
    if k:
        hb = randint(1,n-k+1)
        n -= hb
        k -= 1
        print("第%d个红包是%d元,红包剩余%d元" % (abs(k-10), hb, n))

#运行结果
第1个红包是6元,红包剩余94元
第2个红包是5元,红包剩余89元
第3个红包是18元,红包剩余71元
第4个红包是26元,红包剩余45元
第5个红包是11元,红包剩余34元
第6个红包是29元,红包剩余5元
第7个红包是2元,红包剩余3元
第8个红包是1元,红包剩余2元
第9个红包是1元,红包剩余1元
第10个红包是1元,红包剩余0元

点评

红包的大小是递减的,最好考虑对前后的人都是公平的。  发表于 2017-9-9 11:55

评分

参与人数 1荣誉 +4 鱼币 +4 收起 理由
冬雪雪冬 + 4 + 4

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-9 01:05:50 | 显示全部楼层
import random
money = [0]*10
while(100 != money[0] + money[1] + money[2] + money[3] + money[4] + money[5] + money[6] + money[7] + money[8] + money[9]):
    for i in range(10):
        money[i] = random.randint(1,50) #缺点:当randint第二个参数过大时,python会很慢,所以目前调成50,我微信抢红包从不过50...
for i in money:
    print(i)
其中一个结果:
1
12
4
25
1
4
8
4
9
32

点评

反复凑100,效率的确很低  发表于 2017-9-9 11:56

评分

参与人数 1荣誉 +4 鱼币 +4 收起 理由
冬雪雪冬 + 4 + 4

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2017-9-9 01:23:15 | 显示全部楼层
def hongbao(money,number):
    import random
    while money:
        if number:
            bb = random.randint(1,money - number +1)
            print(bb)
            money -= bb
            number -= 1
hongbao(100,10)

评分

参与人数 1荣誉 +4 鱼币 +4 收起 理由
冬雪雪冬 + 4 + 4

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-9 10:02:34 From FishC Mobile | 显示全部楼层
import random
def hongbao(a,b):
    x=[]
    for i in range(b-1):
        c =random.randint(1,a-b+i)   
        a = a-c
        x.append(c)
    x.append(a)
    return(x)
a=100
b=10
h=hongbao(a,b)
print(h)
这是刚开始的想法 第一个随机拿 后面的人 挨个从剩下的随机拿 后来发现 后面拿的钱都很少 如果是分红包 显得不公平
import random
def hongbao1(a,b):
    x=[]
    y=[]
   
    for i in range(b-1):
        x.append(random.randint(1,b))         
    for i in x:      
        y.append(int(i/sum(x)*a))
    y.append(a-sum(y))
    return(y)
a=100
b=10
g=hongbao1(a,b)
print(g)
这是后来写的  先随机 生成9个数 然后 每个数除以 他们的和 最后一个人拿 零头(为了凑够100块) 虽然最后一个人不算公平 但谁叫他抢的慢呢
我觉得自己掌握的代码太少了 来看看大神都是怎么做的

评分

参与人数 1荣誉 +4 鱼币 +4 收起 理由
冬雪雪冬 + 4 + 4

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-9 10:16:30 From FishC Mobile | 显示全部楼层
楼主 思维强大
看楼上的  突然有个 想法 10个人  每次 随机发给一个人 一块钱  发100次   就完事了
import random
def hongbao2(a,b):
    x=[0]*b
    for i in range(a):
        x[random.randint(0,9)] += 1
    return(x)
g=hongbao2(a,b)
print(g)

点评

这个办法也挺好  发表于 2017-9-9 11:57

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
冬雪雪冬 + 5 + 5

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 4 反对 0

使用道具 举报

发表于 2017-9-9 10:48:24 | 显示全部楼层
look  and study
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-9 11:46:34 | 显示全部楼层
from random import randint
def hongbao(money, size):
    t = []
    t.append(money)
    for i in range(1,size+1): # size+1 为了最后一个红包不为0.
        if i == size-1:
            t.append(money - sum(t))
        else:
            t.append(max(t) - randint(1, max(t)-1))
            t[t.index(max(t))] = max(t) - t[-1]
    t.remove(0)
    return t

评分

参与人数 1荣誉 +4 鱼币 +4 收起 理由
冬雪雪冬 + 4 + 4

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-9 13:16:38 | 显示全部楼层
本帖最后由 solomonxian 于 2017-9-9 14:34 编辑

用正态分布吧,可能比较符合现实
标准差对应分散程度,按循环次数上取u-3σ>= 0下最大比较好,

但是如果分散一点貌似更好玩,取 u/2, 小数点保留1位好了
有 2.5% 概率出现负数,那就递归再来一遍,钱一定要比人数多大
import random, math
def fun(money, people):
    lst = sorted(round(random.gauss(money//people, money//people//2),1) for _ in range(people)) 
    temp = round(money - math.fsum(lst),1)
    
    num = sorted([(temp,0),(temp+0.1,-1)], key=lambda x :abs(x[0]))[0][1] # 因为精度是0.1
    lst[num] = round(lst[num] + temp, 1)
    random.shuffle(lst)
    return fun(money, people) if sorted(lst)[0]<=0 else lst

评分

参与人数 1荣誉 +4 鱼币 +4 收起 理由
冬雪雪冬 + 4 + 4

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2017-9-9 13:55:50 | 显示全部楼层
from random import randint

def hb(n):
    money =100
    k =1
    while n:
        person_money = randint(0,money)
        #为保证公平,设置范围且金额不能为0.否则重新随机
        if n>1:
            while person_money > money/(n-1) or person_money ==0:
                person_money = randint(0,money)
        
        else :
            person_money = money
            
        print('第%d个人的红包是%d元'%(k,person_money))
        money -= person_money
        n -=1
        k +=1
         
hb(10)

评分

参与人数 1荣誉 +4 鱼币 +4 收起 理由
冬雪雪冬 + 4 + 4

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-9 14:35:18 | 显示全部楼层
学习一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-9 15:06:10 From FishC Mobile | 显示全部楼层
微信红包的分配策略是随机数取1~剩余均值的2倍,倒数第二个人取1~剩余总数,最后一个人全收。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-9 18:08:20 | 显示全部楼层
import random
N=100
num = 10
while(N>1):
   money = random.randint(1,N-num+1)
   print(money)
   N-=money
   num-=1
print(N)

评分

参与人数 1荣誉 +4 鱼币 +4 收起 理由
冬雪雪冬 + 4 + 4

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-9 19:10:17 | 显示全部楼层
from random import randint as r

i=0
def f(n):
    global i
    while i<10:
        a=r(1,n-9+i)
        print(a)
        i+=1
        return f(n-a)
f(100)
————————————————
运行结果
58
3
10
23
1
1
1
1
1
1
>>>
===================== RESTART: D:\Python36-32\caogao.py =====================
56
15
7
5
2
10
1
1
1
2
>>>

评分

参与人数 1荣誉 +4 鱼币 +4 收起 理由
冬雪雪冬 + 4 + 4

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-9 22:50:02 | 显示全部楼层
本帖最后由 schweinfan 于 2017-9-9 22:51 编辑
import random as r
rest_money = 100
rest_num = 10
for i in range(1,10):
    current = r.randint(1, rest_money - rest_num + 1)
    print('第%d个红包,金额为%d元' % (i, current))
    rest_num  -= 1
    rest_money = rest_money - current
print('第10个红包,金额为%d元,红包已抢完' % rest_money)
输出为:
第1个红包,金额为16元
第2个红包,金额为10元
第3个红包,金额为33元
第4个红包,金额为13元
第5个红包,金额为9元
第6个红包,金额为5元
第7个红包,金额为3元
第8个红包,金额为3元
第9个红包,金额为4元
第10个红包,金额为4元,红包已抢完
应该是符合题意的,但结果基本都是前面抢到的金额大。。所以还是微信的算法更合理吧

评分

参与人数 1荣誉 +4 鱼币 +4 收起 理由
冬雪雪冬 + 4 + 4

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-10 15:29:55 | 显示全部楼层
from random import randint


list1 = []
for each in range(10):
    list1.append(randint(1,101))

total = sum(list1)

for i in range(10):
    list1[i] = int(100 * list1[i] / total + 0.5)
    
print(list1)
print(sum(list1))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-11 00:07:23 | 显示全部楼层
没思路。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-11 15:48:33 | 显示全部楼层
6666666666666666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-11 17:19:24 | 显示全部楼层
```python
import random

num = [random.random() for _ in range(10)]
summ = sum(num)
a=[]
for i in num:
    temp = i / summ * 100
    print('天了噜!发财了抽中%s元'%int(temp+0.5))

```

评分

参与人数 1荣誉 +2 鱼币 +2 收起 理由
冬雪雪冬 + 2 + 2

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-11 21:12:07 | 显示全部楼层
100
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-23 01:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表