鱼C论坛

 找回密码
 立即注册
查看: 3435|回复: 12

[已解决]怎么简化我的代码?纯新手

[复制链接]
发表于 2023-2-19 17:29:43 | 显示全部楼层 |阅读模式
20鱼币
卡片
题目:
小蓝有很多数字卡片,每张卡片上都是数字 0到9
小蓝准备用这些卡片来拼一些数,例如小蓝有 30 张卡片,其中 0到9 各3张,则小蓝可以拼出 1到10,
但是拼11时卡片1已经只有一张了,不够拼出11

现在小蓝手里有 0到9 的卡片各 2021 张,共20210张,请问小蓝可以从 1 拼到多少?
a = b = c = d = e = f = g = h = i = j = 2021
# 0到9 卡片的张数都是2021张

number = 1
while a > 0 and b > 0 and c > 0 and d > 0 and e > 0 and f > 0 and g > 0 and h > 0 and i > 0 and j > 0:
    a -= str(number).count("0")
    b -= str(number).count("1")
    c -= str(number).count("2")  
    d -= str(number).count("3")
    e -= str(number).count("4")
    f -= str(number).count("5")
    g -= str(number).count("6")
    h -= str(number).count("7")
    i -= str(number).count("8")
    j -= str(number).count("9")
    number += 1
if a <= 0 or b <= 0 or c <= 0 or d <= 0 or e <= 0 or f <= 0 or g <= 0 or h<= 0 or i <= 0 or j <= 0:
    number -= 1
print(number)

感谢大佬
最佳答案
2023-2-19 17:29:44
本帖最后由 元豪 于 2023-2-19 18:31 编辑

个人比较喜欢用列表
u = [2021] * 10
# 0到9 卡片的张数都是2021张
o = False
number = 1
while sum(u) > 0:
    for i in range(1, 11):
        # print(str(number).count(str(i)))
        u[i - 1] -= str(number).count(str(i))
        if u[i - 1] < 0:
            o = True
    if o:
        break
    number += 1
number -= 1
print(number)

最后一个if可以去掉 , 因为已经跳出循环表示肯定 <= 0 了

最佳答案

查看完整内容

个人比较喜欢用列表 最后一个if可以去掉 , 因为已经跳出循环表示肯定
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-19 17:29:44 | 显示全部楼层    本楼为最佳答案   
本帖最后由 元豪 于 2023-2-19 18:31 编辑

个人比较喜欢用列表
u = [2021] * 10
# 0到9 卡片的张数都是2021张
o = False
number = 1
while sum(u) > 0:
    for i in range(1, 11):
        # print(str(number).count(str(i)))
        u[i - 1] -= str(number).count(str(i))
        if u[i - 1] < 0:
            o = True
    if o:
        break
    number += 1
number -= 1
print(number)

最后一个if可以去掉 , 因为已经跳出循环表示肯定 <= 0 了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-19 18:40:08 | 显示全部楼层
小蓝准备用这些卡片来拼一些数,例如小蓝有 30 张卡片,其中 0到9 各3张,则小蓝可以拼出 1到10,
什么意思?
0到9 各3张,那么 则小蓝可以拼出 1到10 是什么意思?
怎么拼出的10 ?
不是3张么?
999行不?
从0到999有问题么?
或者说从000到999这样?
3张都选9么?不可以?

但是拼11时卡片1已经只有一张了,不够拼出11
一共有几张1?
3张吧?
怎么,就能用1张1?

可能是我的理解能力不行吧
反正我是看不懂你这题目
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-19 18:42:16 | 显示全部楼层
lst = [2021] * 10
isbreak = False
n = 1
while sum(lst) > 0:
    for i in range(10):
        lst[i] -= str(n).count(str(i))
        if lst[i] < 0:
            isbreak = True
    if isbreak:
        break
    n += 1
n -= 1
print(n)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-19 18:44:44 | 显示全部楼层
哦,原来是使用过的卡片之后就不能用了,卡片是一次性的,早说么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-19 19:32:25 | 显示全部楼层
#!/usr/bin/env python
#coding=utf-8

import itertools

def count_if(iterable, condition):
    result = 0
    for i in iterable:
        if condition(i): result += 1
    return result

def card_count(n):
    card = 10 * [n]
    for i in itertools.count():
        for j in range(len(card)):
            card[j] -= str(i).count(str(j))
        if count_if(card, lambda x: x < 0):
            return i - 1

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

使用道具 举报

 楼主| 发表于 2023-2-20 11:14:50 | 显示全部楼层
元豪 发表于 2023-2-19 18:30
个人比较喜欢用列表

倒数第二行代码 为什么要number-1呢?这里我没看懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-20 16:02:31 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-20 19:18:39 | 显示全部楼层
无理想的闲鱼 发表于 2023-2-20 11:14
倒数第二行代码 为什么要number-1呢?这里我没看懂

这里原来是你的if语句 , 但是可以删除掉
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-20 19:19:26 | 显示全部楼层

你确定不是我的代码只是换了一下变量名
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-20 20:28:39 | 显示全部楼层
counts = [2021]*10
number = 1

while all(x > 0 for x in counts):
    counts = [a - str(number).count(str(i)) for i, a in enumerate(counts)]
    number += 1

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

使用道具 举报

发表于 2023-2-20 21:50:09 | 显示全部楼层
可以使用列表和循环来减少代码的冗余,并使用更高效的算法。下面是一个优化过的代码:

python
Copy code
nums = [2021] * 10  # 使用列表代替重复赋值操作
number = 1
while all(num > 0 for num in nums):  # 使用 all 函数判断列表中的所有元素是否都大于 0
    for digit in str(number):
        nums[int(digit)] -= 1
    number += 1
print(number - 1)  # 减一是因为在最后一次循环中 number 超出了范围
这个代码使用列表 nums 来代替了重复的赋值操作,并使用 all 函数来判断所有元素是否都大于 0。在每次循环中,将 number 转换为字符串并遍历其中的每个数字。然后,将 nums 中对应数字的计数器减去 1。最后,如果所有数字的计数器都大于 0,则 number 加 1,直到有一个数字的计数器降至 0。最后输出 number - 1 是因为在最后一次循环中,number 超出了范围,因此需要将其减去 1。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-2-20 22:00:31 | 显示全部楼层
可以使用贪心算法来解决这个问题。我们可以先将数字卡片按照数字大小从大到小排序,然后从 1 开始依次尝试能否拼出每一个数。

具体的算法步骤如下:

将数字卡片按照数字大小从大到小排序。
从数字 1 开始,依次尝试能否用卡片拼出每个数。如果能拼出某个数,则记录下来,并将已使用的卡片从卡片列表中移除。
直到不能再拼出更多的数为止,返回已记录下的最大数。
以下是 Python 代码实现:

python
Copy code
def max_num_from_cards(cards):
    # 将数字卡片按数字从大到小排序
    cards.sort(reverse=True)
    # 记录已拼出的数的集合
    used_nums = set()
    # 尝试拼出从 1 开始的每个数
    for num in range(1, 20211):
        # 将当前数转化为卡片组合
        num_str = str(num)
        num_cards = [int(c) for c in num_str]
        # 判断当前数是否可以用卡片拼出
        if all(num_cards.count(i) <= cards[i] for i in range(10)):
            # 如果可以拼出当前数,则将其记录下来,并将已使用的卡片从列表中移除
            used_nums.add(num)
            for i in range(10):
                cards[i] -= num_cards.count(i)
        else:
            # 如果无法拼出当前数,则结束拼数过程
            break
    # 返回已记录下的最大数
    return max(used_nums)
使用上述函数可以得到小蓝可以拼出的最大数,例如:

python
Copy code
cards = [2021] * 10
max_num = max_num_from_cards(cards)
print(max_num)  # 输出:20210
因为小蓝手里有 0 到 9 的卡片各 2021 张,共 20210 张,因此最大可以拼出的数为 20210。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-23 02:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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