本文主要是介绍湖南大学第十四届ACM程序设计大赛 K The Right-angled Triangles,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
链接:https://ac.nowcoder.com/acm/contest/338/K
来源:牛客网
题目描述
Consider the right-angled triangles with sides of integral length.
Give you the integral length of the hypotenuse of a right-angled triangle. Can it construct a right triangle with given hypotenuse c such that the two legs of the triangle are all . integral length?
输入描述:
There are several test cases. The first line contains an integer T(1≤T≤1,000), T is the number of test cases.The following T lines contain T test cases, each line contains one test case. For each test case, there is an integer : c, the length of hypotenuse.(1≤c≤45,000).
输出描述:
For each case, output Yes if it can construct a right triangle with given hypotenuse c and sides of integral length , No otherwise.
示例1
输入
复制
4 5 6 15 13
输出
复制
Yes No Yes Yes
题目大意:
考虑具有整型长度的直角三角形。
给出直角三角形斜边的长度。它能不能构造一个直角三角形,斜边c是已知的,使得三角形的两条边都是整数?
输入描述:
有几个测试用例。第一行包含一个整数T(1≤T≤1000),T是测试用例的数量。
下面的T行包含T个测试用例,每一行包含一个测试用例。对于每个测试用例,都有一个整数:c,斜边的长度。(c 1≤≤45000)。
输出描述:
对于每一种情况,如果它能构造出斜边c和整型长度的直角三角形,则输出Yes,否则输出No。
示例1
输入
4
5
6
15
13
输出
Yes
No
Yes
Yes
分析:
有两种方法:
1。暴力枚举:题目提供的可能测试数据相对较弱,所以可以利用枚举的方法枚举每一个整数进行尝试,但枚举范围要缩小到
i*i<=c/2;c/2以后的数跟之前就重复了,同时如果不缩小范围的话就超时了。
#include<iostream>
#include<cmath>
using namespace std;
int main()
{long long c,n,ans,a,b;cin>>n;//输入测试次数while(n--){ans=0;cin>>c;//输入斜边c=c*c;for(int i=1;i*i<=c/2;i++)//只需要尝试c/2之前的即可,c/2之后的重复{a=sqrt(c-i*i);//求另一个直角边,如果符合条件答案为1直接跳出循环if(a*a==c-i*i){ans=1;break;}}if(ans==1)cout<<"Yes"<<endl;elsecout<<"No"<<endl;}
}
2.这个题很容易想到的一个思路就是暴力枚举。是的,我们给的解题方法也是暴力枚举。但是,直接枚举的复杂度是O(c2),会超时(TLE)。所以我们需要将问题转化一下,使得枚举的复杂度是O(c)。
• 如果三角形三边满足如下关系,则是直角三角形。
• a=m^2-n^2
• b=2mn
• c=m^2+n^2
解释:这是本原勾股数 因为
a^2+b^2
=(m^4 + n^4)- 2×m^2×n^2+(2mn)^2
=(m^2+n^2)^2=c^2
• 所以如果斜边长度能够表示成2个正整数的平方和,则能使得三边都是正整数。这样枚举的复杂度是O( c)。
• 另外,如果斜边长度是一个合数,其有一个因子能表示为2个正整数的平方和,那么也能使得三边都是正整数。比如c=15,有因
子5=12+22,那么也是可以构成三边全是整数的直角三角形,每边长度乘以3即可。就是( 9, 12, 15)
#include <stdio.h>
#define N 45001
int MK[N]={0},SQ[213];
int i,j,k;
//MK数组标记能否是整数三角形,为0表示不能,非0表示可以, SQ数组记录数的平方值
int main()
{for(i=1;i<213;++i)SQ[i]=i*i;for(i=1;i<213;++i)for(j=i+1;j<213&&(k=SQ[i]+SQ[j])<N;++j)MK[k]=1; //所有能写成2整数平方和的被标记为能for(i=5;i<22501;++i)if(MK[i]==1)for(j=2;(k=j*i)<N;++j)MK[k]=1; //所有含2整数平方和的因子的正整数被标记为能,类似于筛法求素数的思想scanf("%d",&t);while(t--){scanf("%d",&c);printf("%s\n",MK[c]?"Yes":"No");}return 0;
}
这篇关于湖南大学第十四届ACM程序设计大赛 K The Right-angled Triangles的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!