1. 程式人生 > >Codeforces Round #512 (Div. 2) D.Vasya and Triangle 數學

Codeforces Round #512 (Div. 2) D.Vasya and Triangle 數學

一個 pro href blank pre turn ref define 但是

題面

題意:給你n,m,k,在你在(0,0)到(n,m)的矩形內,選3個格點(x,y都是整數),使得三角形面積為n*m/k,不能找到則輸出-1

題解:由畢克定理知道,格點多邊形的面積必為1/2的整數倍,所以首先n*m/k必須是1/2的整數倍,也就是2*n*m%k要等於0,不等於就輸出-1

然後對於面積,我們知道底?高*1/2=面積,a*b*1/2=n*m/k,我們很顯然想到一種構造方法,(0,0),(0,a),(b,0);

有人就要問,會不會有一種,使得無法找到整數a,b,滿足這種直角三角形點,但是可以在分數的底和高滿足

但其實我們分析,我們要找到整數a,b滿足a*b=2*n*m/k,且a<=n,b<=m.

因為已經滿足過2*n*m%k==0,所以k至少可以被2或者n的一個因子,或者m的一個因子整除,這個被整除的數也至少是2

也就是說2*n*m/gcd(2,n,m)<=n*m(=當且僅當k==2時), 也就是說肯定可以拆成整數a,b;

  那答案就是a=n/(gcd(2*n,k)) b=m/(k/gcd(2*n,k));或者a=n/(k/gcd(2*m,k)) b=m/(gcd(2*m,k)); 滿足a<=n b<=m的那種就是可行方案

 1 #include<bits/stdc++.h>
 2 using namespace std;
3 #define lld long long 4 long long n,m,k; 5 lld gcd(lld a,lld b) 6 { 7 if (b==0) return a; 8 return gcd(b,a%b); 9 } 10 int main() 11 { 12 scanf("%lld%lld%lld",&n,&m,&k); 13 if (n*m*2%k!=0) 14 { 15 printf("NO"); 16 return 0; 17 }
18 printf("YES\n0 0\n"); 19 lld x=gcd(2*n,k),y; 20 y=k/x; 21 x=2*n/x; 22 y=m/y; 23 if (x<=n && y<=m) 24 { 25 printf("%lld %lld\n",x,0ll); 26 printf("%lld %lld\n",0ll,y); 27 }else 28 { 29 x/=2; 30 y*=2; 31 printf("%lld %lld\n",x,0ll); 32 printf("%lld %lld\n",0ll,y); 33 } 34 }

Codeforces Round #512 (Div. 2) D.Vasya and Triangle 數學