题解 CF1030D 【Vasya and Triangle】

· · 题解

在我的blog里看

题意:

n\times m的矩形中找出一个格点三角形,使得S_\triangle=\frac{nm}k,k\ge 2

题解:

首先这个题要求出在n\times m的矩形中,是否存在一个格点三角形,使得这个格点三角形的面积为\frac{nm}k

如果我们直接构造,可能需要枚举的东西太多了,n,m,k都达到了10^9的数量级。但是我们可以发现题目中k一定\ge 2,那么如果能构造,就一定可以被装在这个n\times m的矩形中。因为n\times m的矩形最大可以装下\frac{nm}2的三角形。此时问题转化为能否构造出一个\frac{nm}k的格点三角形,注意这个题还需要输出顶点方案

样例给出了一个合法的数据和一个不合法的数据,一开始感觉上下互质可能会出问题,但是这个题和质数貌似没有关系。但是和约分肯定有关,因此猜想:格点三角形的面积一定是\frac 12的倍数。也就是说,\frac {nm}k约分后,分母不是1就是2

既然是三角形,由于初中老师教过割补法求平面直角坐标系中三角形的面积,那我们就证一下这个猜想。我们构造一个任意的格点三角形,那么这个格点三角形的面积可以表示为一个边与坐标轴平行的矩形,减去三个直角三角形,这三个直角三角形都满足直角边与坐标轴平行。

这个矩形的面积是一个整数,则三角形的面积为S_\triangle=\frac{ab}2。又因为在格点三角形中,ab是整数,所以S_\triangle一定是\frac 12的倍数。

证完这个东西,我们发现三角形就是可构造的了。设要求的三角形面积为S=\frac t2,t\in \mathbb N^*,那么我们只需要在这个n\times m的三角形中找出a\le n,b\le m使得ab=2S=t即可,此时t并不会爆long long。那么一定存在这样一组整数对(a,b)吗?答案是肯定的。

要证存在整数对(a,b)\ \mathrm{St.}\ ab=\frac{2nm}{k},a\le n,b\le m,且\gcd(2nm,k)=k,k\ge 2。那么由于\gcd(2nm,k)=k,除出来的结果是整数,不考虑分子上的2,则这个整数应该只含n,m的质因子,且ab\le nm

单独讨论分子上的2

Code:

#include<cstdio>
#include<cstring>
#include<cmath>
long long n,m,k;
long long gcd(long long a,long long b)
{
    if(!b)
        return a;
    return gcd(b,a%b);
}
int main()
{
    scanf("%I64d%I64d%I64d",&n,&m,&k);
    long long tt=n>m?n:m;
    int flag=(n>=m);
    k=k;
    long long t=n>m?n:m;
    n=n*m;
    long long tmp=gcd(n,k);
    n/=tmp;
    k/=tmp;
    if(k>2)
    {
        puts("NO");
        return 0;
    }
    if(k==1)
        n*=2;
    long long up=sqrt(n)+1;
    for(int i=(n/tt)?(n/tt):1;i<=up;++i)
        if(n%i==0)
            if(n/i<=t)
            {
                n=n/i;
                m=i;
                break;
            }
    puts("YES");
    puts("0 0");
    if(flag)
    {
        printf("%I64d 0\n",n);
        printf("0 %I64d\n",m);
    }
    else
    {
        printf("%I64d 0\n",m);
        printf("0 %I64d\n",n);
    }
    return 0;
}