【每日一题】备战冲击蓝桥杯国赛——Python程序设计 | Day13 | 货物摆放 | 真题代码解析
每天刷一道题,话不多说,先刷近两年的题吧,从2020的开始,如果有一起的可以加入我们!!!
一起来刷题,冲击国赛!!!
扫码 我的主页 网页左边下方 群二维码。
加入方式:可以在下方的微信名片加我,然后拉你入群。(记得备注暗号:我要拿国奖)
2021年第十二届蓝桥杯赛题总览
2020年的题就是这些,类型分为两种,分别是结果填空和程序设计,我们每天刷一道题,省赛没问题!
直线 (题目)
(本题总分:5分)
官方练习系统:https://www.lanqiao.cn/problems/1463/learning/
—>【问题描述】
—>【结果描述】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
解析
通过阅读题干,本题——难度一般:⭐⭐
考察类型:枚举、数论
考察知识点:集合set()
分析:
由题意可得,长宽高各为 ,给出了计算方案的公式,也就是满足 .
示例给出:当n=4时,有6中排列组合的方案。
所以,我们只需要满足公式得到结果为: ,即可。十六位数字,三个数相乘,那么单个长宽高可高可低,也就是一位数~十六位数的长度。
如何确定长宽高呢,容易想到的是枚举,我们可以定一个参数,然后再相除,如果整除则留下来,然后不断遍历,好像这样会很复杂诶!~但还是可以作为一种方法。
直接暴力三层循环也能出结果,看看需要多长时间,得半个小时!!!极其不推荐!!!
因此,我们可以一步一步的除L、W、H,然后每一步都判断是否可以整除,能整除才能继续运行下去,如不整除那么就直接跳过,这样可以减少大量的迭代时间,而且只需要两层迭代!! 但是,这样还是很慢很复杂,只要迭代就很慢。因为他需要机器一个一个的去尝试,那么怎样才能更快的求解呢?
观察一下公式,是三个数相乘,符合乘法的交换律,是不是意味着,只要 ,只要出现一种方法,那么就相当于有了6种,这样我们只需要顺序的计算一次就行了,然后再乘以6. 但是还是很慢很慢,会超出时间限制!!!
最后,使出必杀技!~
下面直接开干!!!
代码
Python代码实现:
法一:(极不推荐)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/3/7 14:51
# @Author : 府学路18号车神
# @Email :yurz_control@163.com
# @File : Day13.py
import time
n = 2021041820210418 # 2021041820210418
L,W,H = 0,0,0 # 设置长宽高的初值
docker = set() # 设置一个容器
start_time = time.time()
# while length <= 16: # 当长度不超过16时,可继续计算
for i in range(1, n+1):
L = i # 赋值长
if n % L == 0: # 如果n除以长能出清,那么继续运行下去,这样可以减少后面的迭代次数
n1 = n/L # 先把L给去除了,然后剩下的就是W和H了
for j in range(1, n+1):
W = j # 赋值宽
if n1 % W == 0: # 和上面同理,为了判断是否能整除
n2 = n1/W
H = n2 # 实际此时的n2就是最终的高H,这样我们只需要两层迭代就可以解决啦
nn = L*W*H
print(int(nn), (L,W,H))
if int(nn) == n: # 再次判断最终的相乘结果是否为n
docker.add((L,W,H)) # set集合中不会出现重复的
end_time = time.time()
print("运算时间为:", end_time-start_time)
print(len(docker)) # 计算容器的长度也就是最终方案的次数:2430
示例1:
法二:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/3/7 16:03
# @Author : 府学路18号车神
# @Email :yurz_control@163.com
# @File : demo.py
from math import sqrt
a = 0 # 计数器
n = 2021041820210418
s = list() # 存放临时值
for i in range(1, int(sqrt(n))+1): # 求取n的平方,取出中值
if n%i==0: # 然后再计算一下可否整除n,如果能就加入到list中备用
s.append(i) # 先加入第一个i,后加入被除数,这样就得到了两个值,可能是长宽高中任意的两个
s.append(n/i)
for i in s: # 三层取出相乘
for j in s:
for k in s:
if i*j*k ==n:
a += 1
print(a) # 2430,控制台运行还是超时,自闭了
法三:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/3/7 16:03
# @Author : 府学路18号车神
# @Email :yurz_control@163.com
# @File : demo.py
from math import sqrt
a = 0 # 计数器
n = 2021041820210418
s = list() # 存放临时值
docker = set()
L,W,H =0,0,0
for i in range(1, int(sqrt(n))+1): # 求取n的平方,取出中值
if n%i==0: # 然后再计算一下可否整除n,如果能就加入到list中备用
s.append(i) # 先加入第一个i约数,后加入被除数,这样就得到了两个值,可能是长宽高中任意的两个
s.append(n/i)
# for i in s: # 三层取出相乘
# for j in s:
# for k in s:
# if i*j*k ==n:
# a += 1
for x in s:
L = x # 取出付给L
for y in s:
W = y # 取出值赋给W
if n % (L*W) == 0:
H = n/(L*W)
nn = L*H*W
a += 1
# if int(nn) == n:
# docker.add((L,H,W))
print(a) # 2430,控制台运行还是超时,自闭了
5s不到就运算出来了,不知道为什么还是超出时间限制,估计是因为Python内部机制的原因,计算太慢了,Java和C++还是很快的,emo了,目前只能这样了,填空题,能算出来就行了~
可以得出最终的结果为:2430
由此,我们可以快速得出结果,验证完毕!
- 点赞
- 收藏
- 关注作者
评论(0)