1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| 特殊等腰三角形
考虑底为b = 16,腰为L = 17的等腰三角形。
使用毕达哥拉斯定理,我们可以求出三角形的高是h = √(172 − 82) = 15,恰好比底长小1。
当b = 272而L = 305时,可以算出h = 273,恰好比底长大1,而且这是满足性质h = b ± 1的三角形中第二小的。
对于最小的12个满足h = b ± 1且b,L均为正整数的等腰三角形,求∑ L。
我的思路: 首先,腰长是整数,高度也是整数,所以半个底边长也必须是整数. 所以底边长一定能被2整除.设半个底边长x. 第一种情况:高度h=2x+1 那么L^2=4xx+1+4x+xx=5x^2+4x+1 是一个佩尔方程,直接解就行.
第二种情况:高度h=2x-1,仍然是一个pell方程,直接解就可以了,最后对12个解排序即可, 请给我c++代码,注意用int128 参考pell方程实现: pair<__int128,__int128> pell(__int128* dat,__int128 d,__int128 k=1){/* x^2 -d y^2 =1 求解 */ long double sq=sqrt(d);/* 辅助内存 求解d 答案k次方*/ __int128 ss=sq,m=-1,upper=1,lower=0; if(ss*ss==d)return {-1,-1};/*无解*/ dat[++m]=sq; __int128 a=ss,b=1; do{ b=(d-a*a)/b; dat[++m]=(sq+a)/b; a=dat[m]*b-a; }while((dat[0]<<1)!=dat[m]); for(int i=m-1;i>=0;--i){ swap(upper,lower); upper+=dat[i]*lower; } pair<__int128,__int128> res; if(m&1)res={upper*upper<<1|1,upper*lower<<1}; //求 x^2+dy^2=-1把if else改成res={upper,lower}; else res={upper,lower}; k--; __int128 base[5]={0,res.first,d*res.second,res.second,res.first},rres[5]{0,1,0,0,1}; while(k){ if(k&1)tie(rres[1],rres[2],rres[3],rres[4])=make_tuple(rres[1]*base[1]+rres[2]*base[3],rres[1]*base[2]+rres[2]*base[4],rres[3]*base[1]+rres[4]*base[3],rres[3]*base[2]+rres[4]*base[4]); tie(base[1],base[2],base[3],base[4])=make_tuple(base[1]*base[1]+base[2]*base[3],base[1]*base[2]+base[2]*base[4],base[3]*base[1]+base[4]*base[3],base[3]*base[2]+base[4]*base[4]); k>>=1; } return {rres[1]*res.first+rres[2]*res.second,rres[3]*res.first+rres[4]*res.second}; }
|