运行要求
运行时间限制: 2sec
内存限制: 1024MB
原题链接
题目
有一个高为H,宽为W的巧克力棒。这个巧克力棒由H*W的小块组成,每个小块大小相同。
小明准备把这个巧克力棒切成三块。每次切的时候必须要沿着平行于巧克力棒的边缘来切。
小明尽量保证三块巧克力块大小一致。具体来说的话,这3块巧克力块的最大一块的面积是Smax的话,最小一块的面积是Smin的话。求Smax-Smin的最小值。
输入前提条件
- 2 <= H,W <= 100000
输入
输入都以以下标准从命令行输入
H W
输出
Smax - Smin 的最小值
例1
输入
3 5
输出
0
按照下图的方式去切巧克力的话,可以得到Smax-Smin的最小值 5 - 5 = 0
例2
输入
4 5
输出
2
按照下图的方式去切巧克力的话,可以得到Smax-Smin的最小值 8 - 6 = 2
例3
输入
5 5
输出
4
按照下图的方式去切巧克力的话,可以得到Smax-Smin的最小值 10 - 6 = 4
例4
输入
100000 2
输出
1
例5
输入
100000 100000
输出
50000
读懂题目
就是由一个长为W,块为H的格子数组。横轴轴上选一个Xi,纵轴上选择一个Yi。
然后在Xi,Yi的基础上切割巧克力块。
解题思路
- 首先我们看前提条件,H和W的最大值是100000,也就是说可以进行复杂度为O(N)的for全文探索,但是想进行复杂度为O(N2)的嵌套for探索的话,时间上是来不及的。
- 横轴选定一个Xi,也就是横着切一刀。同样的纵轴上选定一个Yi,也就是竖着切一刀。
如下图所示
- 对于每选择一组Xi,Yi
分为Xi切完,Yi不切完(代码设计可以为验证横轴方向遍历)
分为Xi不切完,Y切完(代码设计可以为验证纵方向遍历)
一共有4种切法
如下图所示
- 下面两种切法的结果都是一样的,不一样的是
左边的切法,在切第2刀的时候,是切上面的。
右边的切法,在切第2刀的时候,是切下面。
这两种切法的结果是一样的,但是为了代码好写,以及不必要的重复计算,我们只取右边的切法。这一点大家自己领悟
如下图所示
- 我们第一反应的是,每一个Xi,Yi的4种切法里面的每一种切法,我们要继续遍历切完后剩下的巧克力块。但是那样的话会产生O(N2)的复杂度。时间上来不及的
如下图所示
- 继续观察题目,我们发现,要找到所有切法的最均等,那么我们在遍历到每一种切法的时候,只需要找到最均等的哪种切法,取最均等的切法的结果就是取该种切法下Smax-Smin的最小值。
- 直觉告诉我们,最近的的解法就是等分第1刀后剩下的巧克力块,或者尽量等分1刀后剩下的巧克力块。如图所示,如果不等分1刀后剩下的巧克力块话,会怎样呢。我们平移第2刀,Smin会变小,Smax-Smin会变大。
如下图所示
- 所以,我们每遍历完Xi或者Yi后,直接二分剩下的巧克力块
代码
S = input().split(" ")
H = int(S[0])
W = int(S[1])
def calculate(h, w):
result = []
for i in range(1, h):
s1 = w * i
s2 = (h - i) * (w // 2)
s3 = (h - i) * w - s2
minValue = min(min(s1, s2), s3)
maxValue = max(max(s1, s2), s3)
result.append(maxValue - minValue)
if i <= h - 1:
s1 = w * i
s2 = ((h - i) // 2) * w
s3 = (h - i) * w - s2
minValue = min(min(s1,s2),s3)
maxValue = max(max(s1,s2),s3)
result.append(maxValue - minValue)
for i in range(1, w):
if i <= w - 1:
s1 = i * h
s2 = ((w - i) // 2) * h
s3 = (w - i) * h - s2
minValue = min(min(s1, s2), s3)
maxValue = max(max(s1, s2), s3)
result.append(maxValue - minValue)
s1 = i * h
s2 = (w - i) * (h //2)
s3 = (w - i) * h - s2
minValue = min(min(s1, s2), s3)
maxValue = max(max(s1, s2), s3)
result.append(maxValue - minValue)
print(min(result))
calculate(H, W)
总结
这道题主要是要考察到Smax-Smax最小的情况是二分剩下的巧克力块
※ 另外,我会在我的微信个人订阅号上推出一些文章,欢迎关注
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。