Hướng dẫn giải của Ghép tam giác
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ậpTác giả: , , ,
Editorial for gheptg: Ghép tam giác
Hiểu bài toán
Cho ba thanh nhựa có độ dài nguyên dương a, b, c. Nhiệm vụ là tìm thời gian tối thiểu (tính bằng phút) cần để kéo giãn một số thanh (mỗi đơn vị độ dài tốn 1 phút) sao cho ba thanh có thể tạo thành một tam giác có diện tích dương.
Điều kiện để ba đoạn thẳng tạo thành một tam giác là: tổng độ dài của hai cạnh ngắn nhất phải lớn hơn độ dài của cạnh dài nhất. Nếu gọi ba cạnh đã sắp xếp theo thứ tự tăng dần là x, y, z (với z là cạnh dài nhất), điều kiện này là: x + y > z.
Nếu tam giác đã hợp lệ (x + y > z), thời gian cần thiết là 0. Nếu chưa hợp lệ, ta cần tăng độ dài của các cạnh sao cho điều kiện thỏa mãn. Do chi phí tăng độ dài của bất kỳ cạnh nào đều như nhau (1 đơn vị độ dài tốn 1 phút), ta nên tập trung vào việc đáp ứng điều kiện tam giác một cách tối ưu nhất.
Các cách tiếp cận
Cách Phân tích trực tiếp theo điều kiện tam giác
#include <stdio.h>
#include <stdlib.h>
int compare(const void *a, const void *b) {
return (*(long long*)a - *(long long*)b);
}
int main() {
long long sides[3];
scanf("%lld %lld %lld", &sides[0], &sides[1], &sides[2]);
qsort(sides, 3, sizeof(long long), compare);
long long x = sides[0];
long long y = sides[1];
long long z = sides[2];
// Kiểm tra xem tam giác đã hợp lệ chưa
if (x + y > z) {
printf("0");
} else {
// Nếu không, ta cần tăng tổng của x và y lên để nó lớn hơn z.
// Mục tiêu: x + y > z
// Hiện tại: x + y <= z
// Cần tăng tổng x + y lên: (x + y) + k > z => k > z - (x + y)
// Giá trị nhỏ nhất của k là z - (x + y) + 1
printf("%lld", z - (x + y) + 1);
}
return 0;
}
- Time Complexity: O(1) (hoặc O(log 3) do sắp xếp 3 phần tử)
- Space Complexity: O(1)
Cách tiếp cận này dựa trên việc nhận ra rằng để tạo thành tam giác, ta chỉ cần quan tâm đến tổng độ dài của hai cạnh ngắn nhất và cạnh dài nhất.
- Sắp xếp ba cạnh theo thứ tự tăng dần: x ≤ y ≤ z.
- Kiểm tra điều kiện tam giác: x + y > z.
- Nếu thỏa mãn, đáp án là 0.
- Nếu không thỏa mãn, ta cần tăng tổng độ dài của hai cạnh ngắn nhất (x và y) sao cho tổng này vượt quá z.
- Chi phí tăng độ dài của x hay y là như nhau.
- Lượng cần tăng thêm tối thiểu để (x + y) trở thành (z + 1) là: (z + 1) - (x + y).
- Đáp án là
z - (x - y) + 1. Lưu ý: Cần dùng kiểu dữ liệulong longđể tránh tràn số vì a, b, c có thể lên tới 10^9.
Cách Kiểm tra từng trường hợp vi phạm
#include <stdio.h>
int main() {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
int x = a + b;
int y = a + c;
int z = b + c;
// x là tổng của a, b (cạnh còn lại là c)
// y là tổng của a, c (cạnh còn lại là b)
// z là tổng của b, c (cạnh còn lại là a)
if (x <= c) {
printf("%d", c - x + 1);
} else if (y <= b) {
printf("%d", b - y + 1);
} else if (z <= a) {
printf("%d", a - z + 1);
} else {
printf("0");
}
return 0;
}
- Time Complexity: O(1)
- Space Complexity: O(1)
Cách tiếp cận này kiểm tra trực tiếp từng trường hợp mà tam giác bị vi phạm. Một tam giác không hợp lệ khi một cạnh bằng hoặc lớn hơn tổng hai cạnh còn lại.
- Tính tổng của từng cặp cạnh:
a+b,a+c,b+c. - Kiểm tra từng cặp:
- Nếu
a + b <= c: Cạnhcquá dài. Ta cần tăng tổnga+blên để nó lớn hơnc. Chi phí làc - (a+b) + 1. Sau khi tăng, tam giác(a', b', c)sẽ hợp lệ. - Tương tự cho các trường hợp
a + c <= bvàb + c <= a.
- Nếu
- Nếu không có trường hợp nào bị vi phạm, tam giác đã hợp lệ, chi phí là 0. Cách này không cần sắp xếp nhưng logic kiểm tra rẽ nhánh cũng tương đương.
Cách Giải pháp Logic Đơn giản (Từ các submission)
#include <stdio.h>
int max(int a, int b) { return a > b ? a : b; }
int main() {
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
int maxx = max(a, max(b, c));
int tong = a + b + c - maxx; // Tổng của hai cạnh còn lại
if (tong > maxx) printf("0");
else printf("%d", maxx + 1 - tong);
}
- Time Complexity: O(1)
- Space Complexity: O(1)
Đây là cách tiếp cận tối ưu nhất về mặt ngắn gọn.
- Tìm cạnh dài nhất (
maxx). - Tính tổng của hai cạnh còn lại (
tong). - Điều kiện tam giác là
tong > maxx.- Nếu đúng, in ra 0.
- Nếu sai, ta cần tăng tổng
tonglên để nó vượt quámaxx. Lượng cần tăng làmaxx + 1 - tong. Đáp án chính làmaxx + 1 - tong.
Phân tích độ phức tạp
| Cách tiếp cận | Time | Space | Tên |
|---|---|---|---|
| 1 | O(1) (hoặc O(log 3) do sắp xếp 3 phần tử) | O(1) | Phân tích trực tiếp theo điều kiện tam giác |
| 2 | O(1) | O(1) | Kiểm tra từng trường hợp vi phạm |
| 3 | O(1) | O(1) | Giải pháp Logic Đơn giản (Từ các submission) |
Bài học kinh nghiệm
- Điều kiện tam giác ABC: Hai cạnh ngắn nhất cộng lại phải lớn hơn cạnh dài nhất.
- Vì chi phí kéo dài các thanh như nhau, ta chỉ cần tập trung vào việc làm sao cho tổng hai cạnh ngắn nhất vượt quá cạnh dài nhất.
- Sử dụng
long longlà bắt buộc do giới hạn độ dài cạnh lên tới 10^9.
Lỗi thường gặp
- Tràn số integer: Nếu dùng
intđể tính tổnga + b + ckhi a, b, c lên tới 10^9, tổng có thể vượt quá giới hạn củaint(khoảng 2*10^9). Cần dùnglong long. - Sai công thức: Tính sai lượng cần tăng thêm. Ví dụ, nếu tổng hai cạnh nhỏ hơn cạnh dài nhất là 5, cần tăng tổng lên tối thiểu là cạnh dài nhất + 1. Lượng tăng là (cạnh dài nhất + 1) - tổng.
- Quên kiểm tra trường hợp đã hợp lệ: Nếu input đã thỏa mãn điều kiện tam giác, output phải là 0.
Bình luận