鱼C论坛

 找回密码
 立即注册
查看: 8297|回复: 65

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

[复制链接]
发表于 2017-8-31 08:42:01 | 显示全部楼层 |阅读模式

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

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

x
题目:
列出所有3个正整数,使它们之和等于20,并算出有多少种可能排列,如
  1. 1 1 18
  2. 1 2 17
  3. ......
  4. 总共有??种排列
复制代码

注:不同的排列次序各算一次,如
  1. 1 1 18
  2. 1 18 1
  3. 18 1 1
复制代码

都要列出。

我的解法

游客,如果您要查看本帖隐藏内容请回复

本帖被以下淘专辑推荐:

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

使用道具 举报

发表于 2017-8-31 09:24:09 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2017-8-31 09:27 编辑
  1. from itertools import product
  2. print(len(['^_^' for each in product(range(1,19), repeat=3) if sum(each)==20]))
复制代码

评分

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

查看全部评分

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

使用道具 举报

发表于 2017-8-31 10:31:29 | 显示全部楼层
本帖最后由 小星星LLL 于 2017-8-31 10:32 编辑
  1. import math
  2. # A(n,m)=n(n-1)(n-2)……(n-m+1)=n!/(n-m)!
  3. # C(n,m)=A(n,m)/A(m,m)=A(n,m)/m!

  4. print(math.factorial(19)/math.factorial(19-3))
  5. # count = 3!*C(19,3)=19!*3!/((19-3)!*3!)=19!/(19-3)!
复制代码
排列组合就好啦
计算机是数学的应用233

评分

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

查看全部评分

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

使用道具 举报

发表于 2017-8-31 11:01:14 | 显示全部楼层
  1. def sum20():
  2.     c = 0
  3.     for i in range(1,19):
  4.         for j in range(1,19):
  5.             for k in range(1,19):
  6.                 if (i+j+k) == 20:
  7. ##                    print(i,j,k)
  8.                     c += 1
  9.     print(c)


复制代码


求一下不重复,怎么算。

评分

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

查看全部评分

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

使用道具 举报

发表于 2017-8-31 11:29:13 | 显示全部楼层
bush牛 发表于 2017-8-31 11:01
求一下不重复,怎么算。

那就剔除重复的即可。
  1. from itertools import product
  2. sets = []
  3. for each in product(range(1,19), repeat=3):
  4.         if sum(each) == 20 and sorted(list(each)) not in sets:
  5.                 sets.append(sorted(list(each)))
  6. print(len(sets))
  7. print(sets)
复制代码

33
[[1, 1, 18], [1, 2, 17], [1, 3, 16], [1, 4, 15], [1, 5, 14], [1, 6, 13], [1, 7, 12], [1, 8, 11], [1, 9, 10], [2, 2, 16], [2, 3, 15], [2, 4, 14], [2, 5, 13], [2, 6, 12], [2, 7, 11], [2, 8, 10], [2, 9, 9], [3, 3, 14], [3, 4, 13], [3, 5, 12], [3, 6, 11], [3, 7, 10], [3, 8, 9], [4, 4, 12], [4, 5, 11], [4, 6, 10], [4, 7, 9], [4, 8, 8], [5, 5, 10], [5, 6, 9], [5, 7, 8], [6, 6, 8], [6, 7, 7]]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-31 13:06:48 | 显示全部楼层
啊啊啊啊啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-31 13:48:35 | 显示全部楼层
一个循环 三个参数
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-31 15:56:12 | 显示全部楼层
[1, 1, 18],    [1, 2, 17],    [1, 3, 16],    [1, 4, 15],    [1, 5, 14],   [1, 6, 13],   [1, 7, 12],    [1, 8, 11],    [1, 9, 10], [2, 2, 16],    [2, 3, 15],    [2, 4, 14],    [2, 5, 13],    [2, 6, 12],   [2, 7, 11],   [2, 8, 10],    [2, 9, 9],      [3, 3, 14], [3, 4, 13],    [3, 5, 12],    [3, 6, 11],   [3, 7, 10],    [3, 8, 9],     [4, 4, 12],   [4, 5, 11],    [4, 6, 10],    [4, 7, 9], [4, 8, 8],      [5, 5, 10],    [5, 6, 9],     [5, 7, 8],      [6, 6, 8],     [6, 7, 7]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-31 16:32:46 | 显示全部楼层
jerryxjr1220 发表于 2017-8-31 11:29
那就剔除重复的即可。

33

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

使用道具 举报

发表于 2017-8-31 16:49:50 From FishC Mobile | 显示全部楼层
本帖最后由 suloman 于 2017-8-31 16:53 编辑

t = 0
for i in range(1,19):
    for j in range(1,19):
        for k in range(1,19):
            if i+j+k == 20:
                print("%d %d %d" % (i,j,k))
                t+=1
print("总共有%d种"%t)

评分

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

查看全部评分

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

使用道具 举报

发表于 2017-8-31 16:56:02 | 显示全部楼层
def compute():
    count = 0
    for i in range(1,20):
        for j in range(1,20):
            for k in range(1,20):
                if i+j+k == 20:
                    print i,j,k
                    count +=1
    print ('total is :'+str(count))


total is:171

评分

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

查看全部评分

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

使用道具 举报

发表于 2017-8-31 18:15:13 | 显示全部楼层
计算 3个正整数之和等于 n 的排列可能
踏实的计算,两层循环
  1. def cal_1(n):
  2.     result = 0
  3.     for i in range(1,n-1):
  4.         for j in range(1,n-1):
  5.             if n-i-j >0:
  6.                 result += 1
  7.     return result
复制代码

用itertools,笛卡尔积
这个可能是最慢的
  1. import itertools as it

  2. def cal_2(n):
  3.     return sum(1 for i in it.product(range(1,n-1),repeat=3) if sum(i)==n)
复制代码

用numpy,3维数组,
这个应该是最快的
  1. import numpy as np

  2. def cal_3(n):
  3.     a = np.arange(1,n-1)
  4.     return len(np.where((a +a.reshape(-1,1) +a.reshape(-1,1,1)) ==n)[0])
复制代码

n=20 的话应该就是:171种

评分

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

查看全部评分

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

使用道具 举报

发表于 2017-8-31 18:26:30 | 显示全部楼层
  1. for i in range(1, 19):
  2.     for j in range(1, 20 - i):
复制代码

缩小了第二层循环的范围,还避免了判断,很巧啊
我就想着直积,没想到

评分

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

查看全部评分

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

使用道具 举报

发表于 2017-8-31 22:46:03 | 显示全部楼层
  1. count = 0
  2. for i in range(1,21):
  3.     for j in range(1,21-i):
  4.         for k in range(1,21-i-j):
  5.             if i+j+k == 20:
  6.                 print(i,j,k)
  7.                 count +=1
  8. print('一共%d中组合'% count)
复制代码

评分

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

查看全部评分

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

使用道具 举报

发表于 2017-9-1 11:09:52 | 显示全部楼层
刚学Python的渣渣,把最渣的代码奉上。。。。。求指教优化
  1. import itertools

  2. def First_Method():
  3.         #"""最简单的暴力枚举"""
  4.     result = []
  5.     for i in range(1,19):
  6.         for j in range(1,19):
  7.             k = 20 - i - j
  8.             if k < 1:
  9.                     continue
  10.             tmp = [i,j,k]
  11.             result.append(tmp)

  12.     print(result)
  13.     print("有{}种排列".format(len(result)))


  14. def Second_Method():
  15.         """用itertools库生成列表再赛选符合条件的"""
  16.         number = [i for i in range(1,19)]
  17.         tmp = list(itertools.product(*[number] * 3))
  18.         result = [i for i in tmp if (sum(i)==20)]
  19.         print(result)
  20.         print("有{}种排列".format(len(result)))

  21. if __name__ == "__main__":
  22.         First_Method()
  23.         Second_Method()
复制代码

评分

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

查看全部评分

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

使用道具 举报

发表于 2017-9-1 12:00:24 | 显示全部楼层
  1. count = 0
  2. for i in range(1, 18):
  3.     for j in range(1, 18):
  4.         for k in range(1, 18):
  5.             if 20 == (i + j + k):
  6.                 print(i,j,k)
  7.                 count += 1

  8. print('共有' + str(count) + '组')
复制代码

评分

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

查看全部评分

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

使用道具 举报

发表于 2017-9-1 13:50:18 | 显示全部楼层
66
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-1 16:54:53 | 显示全部楼层
本帖最后由 chunchun2017 于 2017-9-1 17:12 编辑
  1. count = 0
  2. list0 = []
  3. for i in range(1,19):
  4.    for j in range(1,19):
  5.        if(20-i-j>0):
  6.            list0.append((i,j,20-i-j))
  7.            count+=1
  8. print('所有可能的排列是:',list0)
  9. print('一共有%d种可能的排列' %  count)
复制代码

===================
运行结果:
所有可能的排列是: [(1, 1, 18), (1, 2, 17), (1, 3, 16), (1, 4, 15), (1, 5, 14), (1, 6, 13), (1, 7, 12), (1, 8, 11), (1, 9, 10), (1, 10, 9), (1, 11, 8), (1, 12, 7), (1, 13, 6), (1, 14, 5), (1, 15, 4), (1, 16, 3), (1, 17, 2), (1, 18, 1), (2, 1, 17), (2, 2, 16), (2, 3, 15), (2, 4, 14), (2, 5, 13), (2, 6, 12), (2, 7, 11), (2, 8, 10), (2, 9, 9), (2, 10, 8), (2, 11, 7), (2, 12, 6), (2, 13, 5), (2, 14, 4), (2, 15, 3), (2, 16, 2), (2, 17, 1), (3, 1, 16), (3, 2, 15), (3, 3, 14), (3, 4, 13), (3, 5, 12), (3, 6, 11), (3, 7, 10), (3, 8, 9), (3, 9, 8), (3, 10, 7), (3, 11, 6), (3, 12, 5), (3, 13, 4), (3, 14, 3), (3, 15, 2), (3, 16, 1), (4, 1, 15), (4, 2, 14), (4, 3, 13), (4, 4, 12), (4, 5, 11), (4, 6, 10), (4, 7, 9), (4, 8, 8), (4, 9, 7), (4, 10, 6), (4, 11, 5), (4, 12, 4), (4, 13, 3), (4, 14, 2), (4, 15, 1), (5, 1, 14), (5, 2, 13), (5, 3, 12), (5, 4, 11), (5, 5, 10), (5, 6, 9), (5, 7, 8), (5, 8, 7), (5, 9, 6), (5, 10, 5), (5, 11, 4), (5, 12, 3), (5, 13, 2), (5, 14, 1), (6, 1, 13), (6, 2, 12), (6, 3, 11), (6, 4, 10), (6, 5, 9), (6, 6, 8), (6, 7, 7), (6, 8, 6), (6, 9, 5), (6, 10, 4), (6, 11, 3), (6, 12, 2), (6, 13, 1), (7, 1, 12), (7, 2, 11), (7, 3, 10), (7, 4, 9), (7, 5, 8), (7, 6, 7), (7, 7, 6), (7, 8, 5), (7, 9, 4), (7, 10, 3), (7, 11, 2), (7, 12, 1), (8, 1, 11), (8, 2, 10), (8, 3, 9), (8, 4, 8), (8, 5, 7), (8, 6, 6), (8, 7, 5), (8, 8, 4), (8, 9, 3), (8, 10, 2), (8, 11, 1), (9, 1, 10), (9, 2, 9), (9, 3, 8), (9, 4, 7), (9, 5, 6), (9, 6, 5), (9, 7, 4), (9, 8, 3), (9, 9, 2), (9, 10, 1), (10, 1, 9), (10, 2, 8), (10, 3, 7), (10, 4, 6), (10, 5, 5), (10, 6, 4), (10, 7, 3), (10, 8, 2), (10, 9, 1), (11, 1, 8), (11, 2, 7), (11, 3, 6), (11, 4, 5), (11, 5, 4), (11, 6, 3), (11, 7, 2), (11, 8, 1), (12, 1, 7), (12, 2, 6), (12, 3, 5), (12, 4, 4), (12, 5, 3), (12, 6, 2), (12, 7, 1), (13, 1, 6), (13, 2, 5), (13, 3, 4), (13, 4, 3), (13, 5, 2), (13, 6, 1), (14, 1, 5), (14, 2, 4), (14, 3, 3), (14, 4, 2), (14, 5, 1), (15, 1, 4), (15, 2, 3), (15, 3, 2), (15, 4, 1), (16, 1, 3), (16, 2, 2), (16, 3, 1), (17, 1, 2), (17, 2, 1), (18, 1, 1)]
一共有171种可能的排列

评分

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

查看全部评分

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

使用道具 举报

发表于 2017-9-1 20:52:52 | 显示全部楼层
sum0 = 0
sum1 = 0
for i in range(1,19):
    for j in range(1,19):
        for k in range(1,19):
            if i + j + k == 20:
                print('%d + %d + %d = 20 ' %(i,j,k,))
                sum0 += 1
                if i ==j or i == k or j == k:
                    sum1 += 1
print('3个整数和为20的个数为:%d' %sum0)
print('其中3个整数有重复现象的个数为:%d' %sum1)

评分

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

查看全部评分

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

使用道具 举报

发表于 2017-9-1 23:23:03 | 显示全部楼层
小星星LLL 发表于 2017-8-31 10:31
排列组合就好啦
计算机是数学的应用233

你的代码我没看错的话是:1~19个数字中任取3个也就是C(19,3),因为可以调换位置,所以你乘了个3!。而根据题意要求所选三个数字和为20,不应该是1~19种任取3个,所以你的答案与题意并不符。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-25 13:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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