Hướng dẫn giải của Cắt bánh sinh nhật


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Lời giải này đang bị ẩn cho đến khi bạn chọn mở ra.

Chúng tôi khuyên bạn nên tự thử giải bài trước. Việc mở lời giải có thể làm lộ mất ý tưởng chính trước khi bạn có cơ hội tự giải.

Bạn phải đăng nhập để mở lời giải này.

Đăng nhập

Tác giả: Hiếu Nguyễn, ngtuananh, TuongLau2025, oqtn75

Hiểu bài toán

Bài toán yêu cầu tìm số lượng nhát dao tối thiểu cần cắt để chia một chiếc bánh hình chữ nhật có kích thước n x m thành n x m miếng bánh hình vuông 1 x 1. Mỗi nhát dao cắt phải đi dọc theo đường thẳng song song với cạnh của bánh và chỉ cắt qua các phần bánh đang nằm liền khối.

Các cách tiếp cận

Cách Trực quan - Tính theo hàng và cột
#include <iostream>
using namespace std;
int main() {
    long long n, m;
    cin >> n >> m;
    // So luong cat theo hang: m - 1
    // So luong cat theo cot: n - 1
    // Tong so cat: (m - 1) + n * (m - 1) = n * m - 1
    // Hoac tuong don: de co k miem phai can k-1 nhat dao
    cout << n * m - 1;
    return 0;
}
  • Time Complexity: O(1)
  • Space Complexity: O(1)

Cách này dựa trên suy nghĩ trực quan về việc cắt bánh. Ta có thể cắt dọc theo các hàng ngang trước. Để chia một hàng ngang dài m thành m miếng 1x1, ta cần m-1 nhát dao. Sau đó, ta có n hàng như vậy. Tuy nhiên, cách này không tối ưu. Cắt tối ưu là chia đôi miếng bánh liên tục. Ban đầu có 1 miếng. Mỗi nhát dao chia một miếng thành hai. Để có tổng cộng N = n*m miếng, ta cần N - 1 nhát dao.

Cách Công thức toán học (Quy luật)
#include <iostream>
using namespace std;
int main() {
    long long n, m;
    cin >> n >> m;
    cout << n * m - 1;
    return 0;
}
  • Time Complexity: O(1)
  • Space Complexity: O(1)

Đây là phương pháp tối ưu nhất. Xét quá trình cắt: Ban đầu có 1 miếng bánh. Mỗi nhát dao cắt một miếng bánh đang có thành 2 miếng. Vậy sau k nhát dao, ta có k+1 miếng bánh. Mục tiêu là có n * m miếng bánh (mỗi miếng 1x1). Do đó, ta cần tìm k sao cho k + 1 = n * m. Suy ra k = n * m - 1. Ví dụ: 3x2 = 6 miếng. Cần 6 - 1 = 5 nhát dao.

Phân tích độ phức tạp

Cách tiếp cận Time Space Tên
1 O(1) O(1) Trực quan - Tính theo hàng và cột
2 O(1) O(1) Công thức toán học (Quy luật)

Bài học kinh nghiệm

  • Bài toán có thể coi là bài toán chia một khối lượng (1 đơn vị) thành n*m phần bằng nhau. Mỗi lần chia tăng số lượng phần lên 1.
  • Số nhát dao cần thiết luôn bằng tổng số miếng bánh cần thiết trừ đi 1.

Lỗi thường gặp

  • Sử dụng biến kiểu int cho n và m, dẫn đến tràn số (overflow) vì n, m có thể lên tới 10^9, tích của chúng lên tới 10^18. Cần dùng long long.
  • Nhầm lẫn giữa số hàng và số cột dẫn đến công thức sai (ví dụ tính n(m-1) thay vì nm-1).

Bình luận

Please read the guidelines before commenting.


Không có bình luận tại thời điểm này.