鱼C论坛

 找回密码
 立即注册
查看: 6040|回复: 72

[已解决]Python:每日一题 261

[复制链接]
发表于 2019-10-22 20:32:23 | 显示全部楼层 |阅读模式
50鱼币
今天的题目难度有点大,请大家认真思考


今天的题目:


扔 n 个骰子,向上面的数字之和为 S。给定 n,请列出所有可能的 S 值及其相应的概率。

示例 1:

输入:n = 1
输出:[[1, 0.17], [2, 0.17], [3, 0.17], [4, 0.17], [5, 0.17], [6, 0.17]]
解释:掷一次骰子,向上的数字和可能为1,2,3,4,5,6,出现的概率均为 0.17。
示例 2:

输入:n = 2
输出:[[2,0.03],[3,0.06],[4,0.08],[5,0.11],[6,0.14],[7,0.17],[8,0.14],[9,0.11],[10,0.08],[11,0.06],[12,0.03]]
解释:掷两次骰子,向上的数字和可能在[2,12],出现的概率是不同的。


欢迎大家一起答题!
最佳答案
2019-10-22 20:32:24
本帖最后由 Unicorn# 于 2019-10-23 21:12 编辑
zltzlt 发表于 2019-10-23 20:08
输入:1
输出:[[1,0.17],[1,0.17],[1,0.17],[1,0.17],[1,0.17],[1,0.17]]
预期结果:[[1,0.17],[2,0.1 ...


哈哈哈哈哈哈我傻了
index函数只会返回它找到的第一个索引值
改了下

  1. def possibility(n):
  2.     f = []
  3.     for i in range(n+1):
  4.         f.append([])
  5.         for j in range(6*n+1):
  6.             f[i].append(0)
  7.     f[0][0] = 1
  8.     for var_n in range(1, n+1):
  9.         for var_s in range(var_n, 6*var_n+1):
  10.             for i in range(1, 7):
  11.                 f[var_n][var_s] += f[var_n-1][var_s-i]
  12.     ans = []
  13.     full = 6**n
  14.     print(f)
  15.     for i in range(n,len(f[n])):
  16.         ans.append([i, float(f[n][i])/full])
  17.     print(ans)
复制代码

最佳答案

查看完整内容

哈哈哈哈哈哈我傻了 index函数只会返回它找到的第一个索引值 改了下

本帖被以下淘专辑推荐:

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

使用道具 举报

发表于 2019-10-22 20:32:24 | 显示全部楼层    本楼为最佳答案   
本帖最后由 Unicorn# 于 2019-10-23 21:12 编辑
zltzlt 发表于 2019-10-23 20:08
输入:1
输出:[[1,0.17],[1,0.17],[1,0.17],[1,0.17],[1,0.17],[1,0.17]]
预期结果:[[1,0.17],[2,0.1 ...


哈哈哈哈哈哈我傻了
index函数只会返回它找到的第一个索引值
改了下

  1. def possibility(n):
  2.     f = []
  3.     for i in range(n+1):
  4.         f.append([])
  5.         for j in range(6*n+1):
  6.             f[i].append(0)
  7.     f[0][0] = 1
  8.     for var_n in range(1, n+1):
  9.         for var_s in range(var_n, 6*var_n+1):
  10.             for i in range(1, 7):
  11.                 f[var_n][var_s] += f[var_n-1][var_s-i]
  12.     ans = []
  13.     full = 6**n
  14.     print(f)
  15.     for i in range(n,len(f[n])):
  16.         ans.append([i, float(f[n][i])/full])
  17.     print(ans)
复制代码

评分

参与人数 1荣誉 +1 贡献 +1 收起 理由
zltzlt + 1 + 1

查看全部评分

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

使用道具 举报

发表于 2019-10-22 20:56:58 | 显示全部楼层
  1. def fun(n):
  2.     import itertools as it
  3.     list1 = [1, 2, 3, 4, 5, 6]
  4.     list2 = []
  5.     for i in it.product(*([list1] * n)):
  6.         list2.append(sum(i))
  7.     list3 = []
  8.     for i in range(1 * n, 6 * n +1):
  9.         list3.append([i, list2.count(i) / len(list2)])
  10.     return list3
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
zltzlt + 1 + 1

查看全部评分

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

使用道具 举报

 楼主| 发表于 2019-10-22 20:59:57 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-22 21:26:59 | 显示全部楼层
本帖最后由 Unicorn# 于 2019-10-23 17:07 编辑

最终版 dp
  1. def possibility(n):
  2.     f = []
  3.     for i in range(n+1):
  4.         f.append([])
  5.         for j in range(6*n+1):
  6.             f[i].append(0)
  7.     f[0][0] = 1
  8.     for var_n in range(1, n+1):
  9.         for var_s in range(var_n, 6*var_n+1):
  10.             for i in range(1, 7):
  11.                 f[var_n][var_s] += f[var_n-1][var_s-i]
  12.     ans = []
  13.     full = 6**n
  14.     for each in f[n][n:]:
  15.         ans.append([f[n].index(each),float(each)/full])
  16.     print(ans)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-22 22:10:15 | 显示全部楼层
  1. def func(n):
  2.     if n == 0:
  3.         return []
  4.     else:
  5.         a = n
  6.         result = {}
  7.         for i in range(1,6*n+1):
  8.             result[i] = 0
  9.         result[1] = 1/6
  10.         result[2] = 1/6
  11.         result[3] = 1/6
  12.         result[4] = 1/6
  13.         result[5] = 1/6
  14.         result[6] = 1/6
  15.         while n > 1:
  16.             for i in range(a-n+1,6*(a-n+1)+1):
  17.                 for j in range(1,7):
  18.                     result[i+j] += 1/(6**(a-n+2))
  19.                     result[i] -= 1/(6**(a-n+2))
  20.             n -= 1
  21.         for i in range(1,a):
  22.             result[i] = 0
  23.         list1 = []
  24.         for each in result:
  25.             if result[each] != 0:
  26.                 list1.append([each,result[each]])
  27.         return list1
复制代码

这是纯粹拿浮点数算的,可能后面几位数字就不大对了。不过今天没空改上去了。
超时警报

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
zltzlt + 1 + 1

查看全部评分

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

使用道具 举报

发表于 2019-10-22 22:13:39 | 显示全部楼层
本帖最后由 Unicorn# 于 2019-10-22 22:23 编辑

我我我又来辽
想到可以用DP
哈哈哈以前机竞的内容还能用
  1. def probility_2(n):
  2.     f = []
  3.     for i in range(n+1):
  4.         f.append([])
  5.         for j in range(6*n+1):
  6.             f[i].append(0)
  7.     for i in range(n+1):
  8.         f[i][i] = 1
  9.     for var_n in range(1, n+1):
  10.         for var_s in range(var_n, 6*var_n+1):
  11.             for i in range(1, 7):
  12.                 f[var_n][var_s] += f[var_n-1][var_s-i]
  13.     ans = []
  14.     full = 6**n
  15.     for each in f[n][n:]:
  16.         ans.append([f[n].index(each),each/full])
  17.     print(ans)
复制代码


!!!!一百个骰子只要3.591205358505249秒
哈哈哈哈哈哈
我太聪明了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-22 22:18:07 | 显示全部楼层
  1. import itertools
  2. def answer(num: int, ndigits=2):
  3.     res = []
  4.     list1 = [sum(i) for i in list(itertools.product([1, 2, 3, 4, 5, 6], repeat=num))]
  5.     min, max = num, num * 6
  6.     z = len(list1)
  7.     for i in range(min, max + 1):
  8.         temp = [i, round(list1.count(i) / z, ndigits)]
  9.         if temp not in res:
  10.             res.append(temp)
  11.     return res
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
zltzlt + 1 + 1

查看全部评分

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

使用道具 举报

发表于 2019-10-22 22:19:05 | 显示全部楼层

  1. def deal(N, s):
  2.     if N< 1 or s < N or s > 6 * N:
  3.         return 0
  4.     elif N == 1:
  5.         return 1
  6.     else:
  7.         resCount = 0  # 骰子的点数之和
  8.         resCount = deal(N - 1, s - 1) + deal(N - 1, s - 2) + deal(N - 1, s - 3) + deal(N - 1, s - 4) + deal(N - 1,s - 5) + deal(N - 1, s - 6) #递归调用,速度比循环要慢,但是代码好懂
  9.         return resCount


  10. N = int(input('请输入骰子个数:'))  # N个骰子
  11. # 输出结果
  12. result = []

  13. for s in range(N, 6 * N + 1):
  14.     N_sum_list = []
  15.     resCount = deal(N, s)
  16.     p = round(float(resCount) / (pow(6, N)), 2)  #点数出现的概率
  17.     N_sum_list.append(s)
  18.     N_sum_list.append(p)
  19.     if N_sum_list:
  20.         result.append(N_sum_list)

  21. print(result)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-22 22:25:37 | 显示全部楼层
def solution(n: int) -> list:
    import collections
    count = 6**n
    res = list()
    tmp = 0
    dfs(tmp, n, res)
    mydict = collections.Counter(res)
    res2 = list()
    for i in mydict:
        res2.append([i, format(mydict[i]/count, '.2f')])
    return res2



def dfs(tmp: int, n: int, res: list):
    if n == 0:
        res.append(tmp)
        return
    for i in range(1,7):
        dfs(tmp+i, n-1, res)

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
zltzlt + 1 + 1

查看全部评分

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

使用道具 举报

发表于 2019-10-22 22:40:09 | 显示全部楼层
本帖最后由 战场原 于 2019-10-23 00:07 编辑
Unicorn# 发表于 2019-10-22 22:13
我我我又来辽
想到可以用DP
哈哈哈以前机竞的内容还能用


666, 用dfs,跑100个骰子感觉电脑都要炸了...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-22 22:54:13 | 显示全部楼层
我想问一下,第二版的python有视频吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-22 23:27:19 | 显示全部楼层
本帖最后由 阴阳神万物主 于 2019-10-22 23:35 编辑

数学是个很好的工具,这里我使用概率学的古典概型
毕竟,满足古典概型的特性:
1.所有可能出现的基本事件只有有限个
2.每个基本事件出现的可能性相等
基本事件:1个骰子扔出某个点数
  1. def solve(n:'int > 0')->list:
  2.     base = dict()
  3.     for i in range(1,7):
  4.         base[i] = 1/6
  5.     old = dict()
  6.     while n:
  7.         if old:
  8.             new = dict()
  9.             for befor in old:
  10.                 for add in base:
  11.                     t_sum = befor + add
  12.                     if t_sum in new:
  13.                         new[t_sum] += old[befor] * base[add] #分类求和
  14.                     else:
  15.                         new[t_sum] = old[befor] * base[add]  #分步求积
  16.             old = new
  17.         else:
  18.             old = base
  19.         n -= 1
  20.     index = list(old)
  21.     index.sort()
  22.     #限定小数位数的输出
  23.     #return [[each,float('%0.2f'%old[each])] for each in index]
  24.     #不限定的
  25.     return [[each,old[each]] for each in index]
  26. if __name__ == '__main__':
  27.     print('示例1 输出:', solve(1))
  28.     print('示例2 输出:', solve(2))
  29.     print('测试大数据 输出:', solve(20))#概率限制两位小数的话,会出现好多0.0
复制代码

评分

参与人数 1荣誉 +2 鱼币 +1 贡献 +2 收起 理由
zltzlt + 2 + 1 + 2

查看全部评分

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

使用道具 举报

发表于 2019-10-22 23:48:57 | 显示全部楼层
Unicorn# 发表于 2019-10-22 22:13
我我我又来辽
想到可以用DP
哈哈哈以前机竞的内容还能用

嘿嘿,要4秒啊。(掩藏不住心中暗暗的窃喜我的一秒都不要就能出结果呢,就是显示时要卡一下。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-22 23:49:57 | 显示全部楼层
wsttlj1985 发表于 2019-10-22 22:54
我想问一下,第二版的python有视频吗?

有的,就是还在更新中
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-23 00:04:06 | 显示全部楼层
阴阳神万物主 发表于 2019-10-22 23:48
嘿嘿,要4秒啊。(掩藏不住心中暗暗的窃喜)我的一秒都不要就能出结果呢,就是显示时要卡一下 ...


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

使用道具 举报

发表于 2019-10-23 00:12:01 | 显示全部楼层
阴阳神万物主 发表于 2019-10-22 23:48
嘿嘿,要4秒啊。(掩藏不住心中暗暗的窃喜)我的一秒都不要就能出结果呢,就是显示时要卡一下 ...


这里是你的代码,加了时间测试
100个骰子列出所有情况,多次测试用时:
4.710269451141357
4.990285634994507
4.661266565322876
3.601206064224243
4.434253454208374
4.696268558502197
平均用时:4.265958343233381秒
DP万岁

  1. def solve(n:'int > 0')->list:
  2.     base = dict()
  3.     for i in range(1,7):
  4.         base[i] = 1/6
  5.     old = dict()
  6.     while n:
  7.         if old:
  8.             new = dict()
  9.             for befor in old:
  10.                 for add in base:
  11.                     t_sum = befor + add
  12.                     if t_sum in new:
  13.                         new[t_sum] += old[befor] * base[add] #分类求和
  14.                     else:
  15.                         new[t_sum] = old[befor] * base[add]  #分步求积
  16.             old = new
  17.         else:
  18.             old = base
  19.         n -= 1
  20.     index = list(old)
  21.     index.sort()
  22.     #限定小数位数的输出
  23.     #return [[each,float('%0.2f'%old[each])] for each in index]
  24.     #不限定的
  25.     return [[each,old[each]] for each in index]
  26. import time
  27. if __name__ == '__main__':
  28.     start = time.time()
  29.     print(solve(100))
  30.     end = time.time()
  31.     print(end - start)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-23 00:12:05 | 显示全部楼层
这更新的时间也太长了吧?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-23 00:13:11 | 显示全部楼层
我想知道,讲不讲WEB方面的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-10-23 00:35:50 | 显示全部楼层
战场原 发表于 2019-10-22 22:40
666, 用dfs,跑100个骰子感觉电脑都要炸了...

DP也可以用dfs+剪枝代替嘛...
不过那也太复杂了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-26 22:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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