洛谷原题

考虑使用 while 循环求解。

理解题目

题目的意思是让我们按照“每一次都切出最大正方形”的切法来切蛋糕。输出最后能切出多少个蛋糕。

做法介绍

先输入进来 \(n\)\(m\)。可以发现,如果 \(n\)\(m\) 相等,那么说明这本身就是一个正方形。所以,输出 \(1\) 即可。
我捏了一个样例,如下图所示:

因为这个 \(5 \times 5\) 的正方形是当前最大的,所以只会有 \(1\) 个正方形。答案为 \(1\)
此部分代码:

if(N==M) return 1;//已经是正方形,只有这 1 个。

Q:如果本身它不是正方形呢?这种情况怎么办?
A:其实,每一个长方形都会被切成若干个正方形。以样例说明为例。如下:

过程为:\(18 \times 5\)\(13 \times 5\)\(8 \times 5\)\(3 \times 5\)\(3 \times 2\)\(1 \times 2\)\(1 \times 1\)。所以得到三个 \(5 \times 5\) 正方形,两个 \(2 \times 2\) 正方形,两个 \(1 \times 1\) 正方形,总共 \(7\) 块。

我们来列一张表看一下。

步数 蛋糕大小 将切出的正方形大小
\(0\) \(18 \times 5\) \(5 \times 5\)
\(1\) \(13 \times 5\) ^
\(2\) \(8 \times 5\) ^
\(3\) \(3 \times 5\) \(3 \times 3\)
\(4\) \(3 \times 2\) \(2 \times 2\)
\(5\) \(1 \times 2\) \(1 \times 1\)
\(6\) \(1 \times 1\) ^

不难发现,每个情况都会变成一个正方形,因为蛋糕本身就可以被看做 \(n \times m\)\(1 \times 1\) 的小正方形。所以一定有解。

小优化

由上面的表格可以看出,有一些情况会切出相同的蛋糕。如果一个一个减的话,效率不太高。如果使用取模运算的话,会快一点。答案从加 \(1\) 就变成了加当前能切出同样大小的蛋糕的数量。
举例:

cnt+=(N/t);//N / t 表示现在能切几个一样大的蛋糕。
N=N%t;//切完后 N 的长度。

比如说,上表可以从第 \(0\) 步跳到第 \(3\) 步。减少运算次数。

AC 记录

AC 记录

AC 代码

#include<bits/stdc++.h>
using namespace std;
int count_square_cakes(int N,int M){
    int cnt=0;
    if(N==M) return 1;//已经是正方形,只有这 1 个。
    while(N>=1&&M>=1){//如果行或列为 0,说明蛋糕已经没了。
        if(N==M){
            return cnt+1;//剩下的已经是一个正方形,cnt 指这个状态之前的答案,1 指剩下这个正方形。
        }
        int t=min(N,M);//最大的正方形的边长看的是长和宽中较小的那一条。
        if(N>=M){
            cnt+=(N/t);//N / t 表示现在能切几个一样大的蛋糕。
            N=N%t;//切完后 N 的长度。
        }else{
            cnt+=(M/t);//M / t 表示现在能切几个一样大的蛋糕。
            M=M%t;//切完后 M 的长度。
        }
    }
    return cnt;//返回需要切出的正方形个数。
}
posted on 2026-06-29 21:35  lz5332t  阅读(2)  评论(0)    收藏  举报