Integer right triangles
If p is the perimeter of a right angle triangle with integral length sides, {a,b,c}, there are exactly three solutions for p = 120.
{20,48,52}, {24,45,51}, {30,40,50}
For which value of p ≤ 1000, is the number of solutions maximised?
题目:
如果 p 是一个直角三角形的周长,三角形的三边长 {a, b, c} 都是整数。对于 p = 120 一共有三组解:
{20,48,52}, {24,45,51}, {30,40,50}
对于 1000 以下的 p 中,哪一个能够产生最多的解?
这个题求的是给出一个周长,求可以产生的直角三角形有多少个;
下面开始分析:
1.有周长,那么设三条边为a,b,c; 通过勾股定理转换展开最终得到
2.那么b得到了就枚举a,那c如何取得到,通过勾股定理;
3.如何取判断,b要创建为double类型,判断时,通过,floor函数向下取整,如果b等于他的向下取整说明b为整数,c = p -a -b,a是枚举的整数,那么c也一定是整数,说明找到了一个解
4 .记录c的值,防止找到重复答案;
5.a和b是直角边,那么就形成,那么,所以缩小了查找范围;
用以上5个条件就可以写代码了,下面是代码实现:
#include <stdio.h> #include <math.h> #include <string.h> #define MAX_N 1000 int cnt[MAX_N + 5]; int s[MAX_N + 5]; int main() { int len = 0, ans = 0; for (int p = 3; p < MAX_N; p++) {//枚举周长 memset(s, 0, sizeof(int) * (MAX_N + 5)); for (int a = 1; a <= p / 3; a++) {//枚举a double b = (pow(p, 2), - 2.0 * p * a) / (2.0 * p - 2.0 * a);//通过公式求b int c = sqrt(b * b + a * a);//勾股定理求c if (b != floor(b) || s[c]) continue;//b不为整数,或者c重复继续枚举下一个 s[c] = 1;//标记当前c已经求过 cnt[p]++;//解+1 } if (len < cnt[p]) { len = cnt[p]; ans = p; } } printf("%d %d\n", ans, len); return 0; }
最终答案:840, 11