一个认为一切根源都是“自己不够强”的INTJ
个人主页:用哲学编程-优快云博客
专栏:每日一题——举一反三
题目链接
目录
菜鸡写法:

import os
import sys
N,K=map(int,input().split())
sizes=[]
output=0
num=100001
for i in range(N):
sizes.append(list(map(int,input().split())))
while num>=K:
output+=1
#print(f"output",output)
num=0
for size in sizes:
H,W=size[0],size[1]
num+=(H//output)*(W//output)
#print(f"num",num)
output-=1
print(output)
代码点评:
这段代码试图解决的是“分巧克力”问题,它使用了一种迭代增加正方形边长的方法来尝试寻找最大的符合条件的正方形边长。代表巧克力尺寸的数组 sizes 被用来存储每个巧克力的宽度和高度。在每次迭代中,代码计算当前边长 output 可以从每块巧克力中切割出多少个指定大小的正方形,并将这些数量累加到 num 中。如果 num 大于或等于小朋友的数量 K,代码增加 output 的值并继续。如果 num 小于 K,则停止循环,并将 output 减去 1,然后打印出最终的 output 值。
点评
- 正确性: 对于给定的问题,这种方法在概念上是可以解决问题的,但效率很低。由于它使用了一个简单的迭代方法,可能会在最坏情况下导致非常长的运行时间。
- 效率: 这段代码没有使用二分搜索,这是解决这类问题更常见的方法。二分搜索的效率会更高,因为它可以减少需要试验的正方形边长的数量。
- 代码质量: 代码简洁明了,但缺少函数封装和注释。加入函数封装和更多注释可以提高代码的可读性和可维护性。
复杂度分析
- 时间复杂度: 最差情况下,output 从 1 开始,一直增加到切割出的最大正方形的最大可能边长。在每次迭代中,代码都会遍历 sizes 数组一次,该数组的长度为 N。因此,最差情况下的时间复杂度为 O(NM),其中 M 表示输出的最大边长。
- 空间复杂度: sizes 数组存储了所有巧克力的尺寸,因此它的空间复杂度为 O(N)。
优化建议
通过二分搜索来优化这个问题的解决方案,可以大幅度提高效率。使用二分搜索时,时间复杂度可以降低到 O(NlogM),其中 M 是可能的最大边长。二分搜索方法会在可能的边长范围内进行逼近搜索,将搜索空间每次减半,直至找到最大可能的边长。这样可以避免不必要的线性搜索,大大提高效率。
如果你想要一个更高效的解决方案,应该考虑实现二分搜索算法。
我要更强!
初次修改:

import os
import sys
N,K=map(int,input().split())
sizes=[]
output=0
num=100001
i,j=0,0
for i in range(N):
tmp=list(map(int,input().split()))
if max(tmp)>j:
j=max(tmp)
sizes.append(tmp)
while i<j:
output=(j+i)//2
#print(f"output",output)
num=0
for size in sizes:
H,W=size[0],size[1]
num+=(H//output)*(W//output)
#print(f"num",num)
if num<K:
#不够,每块巧克力应该更小
j=output
elif num>K:
i=output+1
else:
print(output)
raise SystemExit
output=(j+i)//2
print(output)
这个二分查找代码基本上是正确的,但有一些小问题需要修正。其中一个问题是在最后一个else分支中,如果num正好等于K,那么会打印当前output并退出。但是,可能存在一个更大的output值也能满足条件,所以您应该继续搜索以确认是否有更大的可能性。
另外,在else分支中,既然num等于K,这意味着我们找到了一个有效的解,但不一定是最大的解。我们应该继续向右侧搜索以查找更大的解,即i应该更新为output + 1。最终的output计算也应该在循环外部进行。