codeforces H. Triangle(思考题?)

H. Triangle

time limit per test:1 second
memory limit per test:256 megabytes
input:standard input
output:standard output

There is a right triangle with legs of length a and b. Your task is to determine whether it is possible to locate the triangle on the plane in such a way that none of its sides is parallel to the coordinate axes. All the vertices must have integer coordinates. If there exists such a location, you have to output the appropriate coordinates of vertices.

Input

The first line contains two integers a, b (1 ≤ a, b ≤ 1000), separated by a single space.

Output

In the first line print either “YES” or “NO” (without the quotes) depending on whether the required location exists. If it does, print in the next three lines three pairs of integers — the coordinates of the triangle vertices, one pair per line. The coordinates must be integers, not exceeding 109 in their absolute value.

Examples

input
1 1
output
NO
input
5 5
output
YES
2 1
5 5
-2 4
input
5 10
output
YES
-10 4
-2 -2
1 2

分析

刚刚觉得蛮有意思的题目,WA了六发才发现错在哪里;

给出一个直角三角形的两条直角边 a, b 。现在的任务是,在平面坐标轴找出一个这样的三角形,并使得这个三角形的三条边都不平行于坐标轴(连续改了几次才发现这个条件没看清楚)且坐标可以用整数表示;

因为需要坐标是整数,那么很容易能联想到勾股定理。我们需要确定直角边a,b是不是勾股数;考虑到只有一组输入,直接对a,b的平方枚举1…a-1和1…b-1的平方减去,之后看看剩下的是不是平方数。

方便起见,我们把直角顶点放在原点(0,0)。这样枚举出来的数值就直接是坐标了。

可以先把数值当做第一象限的坐标来枚举a,然后每有符合的a就去枚举b,可以把b放到第四象限(即by变为负数),根据向量点乘的定义,两向量垂直时数量积为零,即需满足 ax*bX+ay*by==0;
同时还要注意一个很容易忽略的条件 :第三条边不能和坐标轴平行。在以原点为顶点只在一四象限的直角三角形构造中,只需要考虑斜边和y轴的关系,再加一个条件判断 ax≠bx 就行了。

二重循环就搞定了。

代码

代码不长,但是细节的地方还是有的。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#define MS(X) memset(X,0,sizeof(X))
#define MSC(X) memset(X,-1,sizeof(X))
typedef long long LL;
using namespace std;
int sq[1005];
int bac[1000005];		//开大空间直接用下标来获取开方的结果
int main(){				//懒得用浮点控精度(其实是不会)
    int a,b,ax,ay,bx,by;
    MSC(sq);MSC(bac);
    for(int i=1;i<=1000;i++){
        sq[i]=i*i;
        bac[i*i]=i;
    }
    scanf("%d%d",&a,&b);
    bool chk=false;
    for(int i=1;i<a;i++){
        if(bac[sq[a]-sq[i]]!=-1){
            ax=i;
            ay=bac[sq[a]-sq[i]];
            for(int i=b-1;i>0;i--){
                if(bac[sq[b]-sq[i]]!=-1&&
                (ax*i)-(ay*bac[sq[b]-sq[i]])==0&&ay!=bac[sq[b]-sq[i]]){
                    chk=true;
                    bx=i;
                    by=bac[sq[b]-sq[i]];
                    break;
                }
            }
            if(chk) break;
        }
    }
    if(!chk){
        printf("NO\n");
        return 0;
    }
    printf("YES\n0 0\n%d %d\n%d %d\n",ax,ay,-bx,by);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值