1. 程式人生 > >Vasya and Triangle 思路+gcd

Vasya and Triangle 思路+gcd

題意:

思路:

令三角形面積為S,

因為題目要求的三角形的三個點是整點,所以2*S是正數,證明:我們在第一象限中找到此三角形的外接矩形,令其面積為S1,令在此矩形中三角形外的部分面積為S2,則有 S = S1 - S2   ->  2*S = 2*S1 - 2*S2;   S2由1or2or3 個直角三角形組成,直角邊都是整數,即證所求;

題目要求 S =  (n * m) / k;   那麼 2*S = (2 * n * m) / k 必須是整數,這樣就一定有解,否則沒有這樣的三角形,

我們令構造的這個三角形為以原點為直角點,直角邊邊長分別為n_(初始值為n),  m_(初始值為m)  的直角三角形

因為  k 可以整除 (2 * n * m), 所以我們思路就是把k分解為 k = a1 * a2 * .... 的形式,同時我們可以令n_或 m_,除以ai,因為可以整除,所以最後可以使得k為1,這樣我們得到的新的n_ 和 m_, 選擇一個乘以係數2並且滿足長寬條件的例子輸出,即為答案;

但是我們分解k的這個過程可以直接簡化為分別跟 n_ m_ 求取gcd;

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100 + 7;

ll n, m, k;

int main() {
    cin >> n >> m >> k;
    ll t = 2 * n * m;
    if(t / k * k != t) {
        return 0*puts("NO");
    }
    ll x = 2LL, n_ = n, m_ = m, k_ = k;
    ll g = __gcd(x, k_);
    x /= g; k_ /= g;
    g = __gcd(n_, k_);
    n_ /= g; k_ /= g;
    m_ /= k_;

    puts("YES");
    if(n_ * x <= n) {
        n_ *= x;
        cout << 0 << " " << 0 << endl;
        cout << 0 << " " << m_ << endl;
        cout << n_ << " " << 0 << endl;
        return 0;
    }
    else if(m_ * x <= m) {
        m_ *= x;
        cout << 0 << " " << 0 << endl;
        cout << 0 << " " << m_ << endl;
        cout << n_ << " " << 0 << endl;
        return 0;
    }
    puts("NO"); // 這一步比賽時沒有嚴格證明,加上一定不會錯
    return 0;
}