Editorial for Tam giác không vuông
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
Spoiler Alert
Hint 1
- Tìm điều kiện tam giác và loại bỏ điều kiện để nó vuông, từ đó suy ra kết quả
Điều kiện độ dài các cạnh: \((a > 0) \ \&\ (b > 0) \ \&\ (c > 0)\)
Điều kiện để tạo tam giác: \((a + b > c) \ \&\ (b + c > a) \ \&\ (c + a > b)\)
Điều kiện để tam giác vuông: \((a^2 + b^2 = c^2) || (b^2 + c^2 = a^2) || (c^2 + a^2 == b^2)\)
Hint 2
- Ta cũng có thể sắp xếp các cạnh thành \(a \leq b \leq c\) để có công thức toán học gọn hơn
Điều kiện độ dài các cạnh: \((a > 0)\) (cạnh bé nhất dương)
Điều kiện để tạo tam giác: \((a + b > c)\) (tổng hai cạnh bé lớn hơn cạnh lớn nhất)
Điều kiện để tam giác vuông: \((a^2 + b^2 = c^2)\) (tổng bình phương hai cạnh góc vuông bằng cạnh huyền)
Hint 3
- Ngoài bignum để nhân hai số lớn, ta có thể chuyển đổi toán học
\(a ^ 2 + b ^ 2 = c ^ 2 \Leftrightarrow \frac{a}{c - b} = \frac{c + b}{a}\)
Đưa hai phân số về tối giản, ta kiểm tra tử với từ, mẫu với mẫu là xong
Reference AC code | \(O(\log max\_val)\) time | \(O(1)\) auxiliary space | Math
C++
/// check a * a + b * b = c * c <=> a / (c - b) = (c + b) / a
inline bool isPythagorean(ll a, ll b, ll c) {
pair<ll, ll> n1 = mp(a, c - b); /// phan so thu nhat
pair<ll, ll> n2 = mp(b + c, a); /// phan so thu hai
ll d1 = gcd(n1.first, n1.second); /// ucln p/s thu nhat
ll d2 = gcd(n2.first, n2.second); /// ucln p/s thu hai
n1.first /= d1; n1.second /= d1; /// toi gian p/s thu nhat
n2.first /= d2; n2.second /= d2; /// toi gian p/s thu hai
return (n1.first == n2.first && n1.second == n2.second); /// kiem tra hai p/s bang nhau
}
/// Voi moi truy van
int query()
{
ll a, b, c;
cin >> a >> b >> c;
/// sort a < b < c
if (a > b) swap(a, b);
if (a > c) swap(a, c);
if (b > c) swap(b, c);
if (a <= 0 || a + b <= c) return cout << "NO\n", 0; /// (a, b, c) khong phai cac canh tam giac
if (isPythagorean(a, b, c)) return cout << "NO\n", 0; /// (a, b, c) la cac canh tam giac vuong
return cout << "YES\n", 0; /// (a, b, c) thoa man
}
Another Approach
- Sài
Hash
+ nhân ấn độ, bạn có thể kiểm tra trong \(O(1)\)
Reference AC code | \(O(\log max\_val)\) time | \(O(1)\) auxiliary space | Math, Hash
C++
/// cac so modulo nguyen to 18 chu so
vector<ll> modulo = {
100055128505716009,100707069199565201,101210328665281103,103509442668384329,103901850164540539,
107164751690556253,108903531991843321,110356113559705927,110437474552301887,111991323706419863
};
/// nhan an do: (a * b) % m
inline ll mulMOD(ll a, ll b, ll m = MOD) {
ll res = 0;
for (a %= m, b %= m; b > 0; a <<= 1, b >>= 1) {
if (a >= m) a -= m;
if (b & 1) { res += a; if (res >= m) res -= m; }
}
return res;
}
/// ham kiem tra: check a * a + b * b = c * c <=> a / (c - b) = (c + b) / a
inline bool isPythagorean(ll a, ll b, ll c) {
for (ll &m : modulo)
if ((mulMOD(a, a, m) + mulMOD(b, b, m)) % m != mulMOD(c, c, m))
return false;
return true;
}
Comments