codeforces 1058 D. Vasya and Triangle(已知面積求整數點座標,規律,利用__gcd把一個數拆成有範圍限制的兩個數相乘)
阿新 • • 發佈:2018-12-24
題意:給出橫座標最大值n,縱座標最大值m,再給出一個k要求,輸出三個整數點座標構成的三角形的面積為m*n/k
思路: (ps:利用__gcd把一個數拆成有範圍限制的兩個數相乘,不是對這個數的質因數貪心得去乘,湊那兩個範圍(這樣不行的) )
令x1=y1=0 ,顯然 每個三角形的都可以平移到以原點為頂點的三角形
即
因為 x2,y3,x3,y2 都是整數 所以 上式2*S的結果也必定是整數,即2mn必定整除k
1.規律:若三角形的三個點的座標均為整數點,他的面積S*2必定是整數
2.那麼就可以把這個三角形看為是直角三角形了,三點座標為(0,0) (x,0) (0,y),面積 S=x*y/2 = m*n/k 即可
3.也所以 m*n 不能整除 k 的必定是輸出 "NO" 了
4.題目就變成了 把一個整數拆成 兩個數(一個<n,一個<m)的乘積 即 或
顯然 k(或 ) 的所有質因數 全部都包含在 m的質因數 "並" n的質因數 中
所以
當k為偶數時:k=k/2; x=n/__gcd(n,k); k=k/__gcd(n,k); y=m/__gcd(m,k); (此時 必定保證了 x<=n&&y<=m,同時等式右邊的分母也被除成了1)【利用__gcd把一個數拆成有範圍的兩個數相乘】
當k為奇數時:x=n/__gcd(n,k); k=k/__gcd(n,k); y=
#include <bits/stdc++.h> //#pragma GCC optimize(3) //#pragma GCC optimize("unroll-loops") //#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define pb push_back #define mkp(a,b) make_pair(a,b) #define PII pair<int,int> #define PLL pair<ll,ll> #define fi first #define se second #define lc (d<<1) //d*2 #define rc (d<<1|1) //d*2+1 #define eps 1e-9 #define dbg(x) cerr << #x << " = " << x << "\n"; #define mst(a,val) memset(a,val,sizeof(a)) #define stn(a) setprecision(a)//小數總有效位數 #define stfl setiosflags(ios::fixed)//點後位數:cout<<stfl<<stn(a); using namespace std; typedef long long ll; typedef unsigned long long ull; const double PI=3.1415926535897932; const int MAXN=1e5+10; const ll mod=1e9+7; ll inline mpow(ll a,ll b){ll ans=1;a%=mod;while(b){if(b&1)ans=(ans*a)%mod;a=(a*a)%mod,b>>=1;}return ans;} int inline sgn(double x){return (x>-eps)-(x<eps);} //a<b:sgn(a-b)<0 priority_queue<int,vector<int>,greater<int> > qu; //up priority_queue<int,vector<int>,less<int> > qd; //dn const int inf = 0x3f3f3f3f; //9 const ll inff = 0x3f3f3f3f3f3f3f3f; //18 ll n,m,k; ll x1,y1,x2,y2,x3,y3; ll x,y; int main() { fio; cin>>n>>m>>k; if((ll)2*n*m%k) {cout<<"NO"<<endl;return 0;} x1=y1=x2=y3=0; int flag=0; if(k%2==0) k/=2,flag=1; x=n/__gcd(n,k);k/=__gcd(n,k); y=m/__gcd(m,k);k/=__gcd(m,k); if(!flag) { if(x*2<n) x*=2; else if(y*2<m) y*=2; } x3=x;y2=y; cout<<"YES"<<endl; cout<<x1<<" "<<y1<<endl; cout<<x2<<" "<<y2<<endl; cout<<x3<<" "<<y3<<endl; }