1. 问题背景与理解
小明遇到了一个有趣的几何切割问题:给定一块矩形材料,如何通过不断切割最大的正方形,最终将整个矩形分解为若干个正方形?这个看似简单的操作背后,其实隐藏着数学的优雅和算法的精妙。
以5×3的矩形为例:
- 第一次切割最大正方形3×3,剩余2×3
- 第二次切割最大正方形2×2,剩余2×1
- 最后将2×1切割为两个1×1正方形
总共得到4个正方形。
这个问题实际上是矩形正方形分割问题的一个特例,与数论中的欧几里得算法有着深刻联系。当我在蓝桥杯竞赛中首次遇到这个问题时,立即意识到它不只是简单的几何操作,而是算法思维的绝佳训练。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法原理剖析
2.1 欧几里得算法的启示
传统的欧几里得算法用于计算两个数的最大公约数(GCD),其核心是:
code复制gcd(a, b) = gcd(b, a mod b)
直到b=0时,a就是最大公约数。
在我们的切割问题中:
- 每次切割最大正方形,相当于用较短边作为边长
- 剩余部分相当于取模运算
- 切割次数就是两数相除的商
2.2 算法改造思路
将GCD算法改造为计数问题的关键步骤:
- 交换保证顺序:确保第一个参数不小于第二个
- 循环切割:只要短边不为零就继续
- 计数累加:用长边除以短边的商作为本次切割的正方形数量
- 更新参数:将短边和余数作为新的长、短边
这种改造完美地将几何问题转化为数论问题,展示了算法思维的灵活性。
3. Java实现详解
3.1 基础实现代码
java复制public class SquareCounter {
public static void main(String[] args) {
int length = 2019;
int width = 324;
System.out.println("正方形总数: " + countSquares(length, width));
}
public static int countSquares(int a, int b) {
// 确保a >= b
if (a < b)
