Triangle

                                               Triangle

题目描述:

            题目的大概意思是,输入直角三角形的任意两条边的长度,然后问我们能否在直角坐标系下表示这个直角三角形而使得直角三角形的每条边都不平行于坐标轴并且直角三角形的三个顶点坐标必须是整数,存在的话,输入直角三角形三个顶点的坐标,否则输出NO。

题目分析:

            输入的两条边存在两种情况,第一种是两条边都是直角三角形的直角边,第二种是一条边是直角三角形的直角边,而另外一条则是直角三角形的斜边。

            按照题目的要求,如果直角三角形的每条边都不垂直于坐标轴的话,就证明每条边都可以用两个平方数去表示,这里需要注意的是,每条边可以表示的平方数可能不止唯一的一对,因此我们首先要将两个能够表示a*a的平方数全部找出来,同理,我们也将两个能够表示b*b的平方数全部找出来,以及能够表示b*b-a*a(这里默认b大于a,如果输入的时候b小于a的话,我们可以将这两个数互相进行交换)的平方数找出来。

            首先我们先对第一种情况进行分析,如果a和b是直角三角形的两条直角边的话,那么我们前面找到的表示a*a以及b*b的两个平方数的开平方可以作为x坐标以及y坐标,然后我们假设直角三角形的一个顶点在(0,0),然后我们求出两条直角边所对应的向量的数量积是否为0,如果是的话,那么就输出直角三角形的三个顶点坐标,然后我们将x坐标和y坐标互换一下,再来判断数量积是否为0。

           对于第二种情况,做法与上面第一种情况一样,我们把b*b换成b*b-a*a就行了,然后像上面一样进行判断就可以得出答案。

代码:

#include <iostream>
#include <cstdio>
#include <stdio.h>
#include <cmath>
#include <math.h>
#include <algorithm>
#include <cstdlib>
#include <stdlib.h>
#include <cstring>
#include <string>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <deque>
#define reg register
#define ll long long
#define ull unsigned long long
#define bll __int128
#define INF 0x3f3f3f3f
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define lowbit(x) (x&(-x))
using namespace std;
vector <int> v[3];
void sqr(int k,int a)
{
	for (reg int i=1;i*i<a;i++)
	{
		int temp=sqrt(a-i*i);
		if (temp==sqrt(a-i*i)) v[k].push_back(i);
	}
}
int main()
{
	int a,b;
	scanf("%d%d",&a,&b);
	a=a*a;b=b*b;
	if (a>b) swap(a,b);
	sqr(0,a);sqr(1,b);sqr(2,b-a);
	for (reg int i=0;i<v[0].size();i++)
	{
		for (reg int j=0;j<v[1].size();j++)
		{
			int ax=v[0][i],bx=v[1][j];
			int ay=sqrt(a-ax*ax),by=sqrt(b-bx*bx);
			ax=-ax;
			int t1=ax*bx+ay*by;
			int t2=ax*by+ay*bx;
			if (t1==0 && ay!=by)
			{
				printf("YES\n");
				printf("0 0\n");
				printf("%d %d\n",ax,ay);
				printf("%d %d\n",bx,by);
				return 0;
			}
			if (t2==0 && ay!=bx)
			{
				printf("YES\n");
				printf("0 0\n");
				printf("%d %d\n",ax,ay);
				printf("%d %d\n",by,bx);
				return 0;
			}
		}
	}
	for (reg int i=0;i<v[0].size();i++)
	{
		for (reg int j=0;j<v[2].size();j++)
		{
			int ax=v[0][i],bx=v[2][j];
			int ay=sqrt(a-ax*ax),by=sqrt(b-a-bx*bx);
			ax=-ax;
			int t1=ax*bx+ay*by;
			int t2=ax*by+ay*bx;
			if (t1==0 && ay!=by)
			{
				printf("YES\n");
				printf("0 0\n");
				printf("%d %d\n",ax,ay);
				printf("%d %d\n",bx,by);
				return 0;
			}
			if (t2==0 && ay!=bx)
			{
				printf("YES\n");
				printf("0 0\n");
				printf("%d %d\n",ax,ay);
				printf("%d %d\n",by,bx);
				return 0;
			}
		}
	}
	printf("NO\n");
	return 0; 
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值