第一次遇到这种限制代码长度的题!spa
如下是个人思路:code
对于公式 :arctan(1/A)=arctan(1/B)+arctan(1/C) blog
先令 : b=actan(1/B) , c=actan(1/C)io
代入上式,得 : actan(1/A)=b+c , 即 :1/A=tan(b+c)class
再用三角公式就能够把上式化成 : 1/A=(B+C)/(BC-1)di
解出 : B=(AC+1)/(C-A)=A+(A*A+1)/(C-A)---------------------------(1)时间
则所求B与C的和为 : SUM(C)=B+C=(C*C+1)/(C-A)while
上式对C求导 : SUM'(C)=(C*C-2*A*C-1)/(C-A)co
令 SUM'(C)=0 , 可得极小值点 : MINC1=A+sqrt(A*A+1) 与 MINC2=A-sqrt(A*A+1)(因为C与B一定大于A,故舍去)math
由式(1)可得,当 C=MINC=A+sqrt(A*A+1) 时,有 B=A+sqrt(A*A+1)
因为B和C本质上是等价的,因此因而可知,B和C一定是一个在 A+sqrt(A*A+1) 左边,一个在 A+sqrt(A*A+1) 右边
因此只要让C往其中一个方向枚举,当找到的B为整数,或者SUM(C)为整数时,便可获得答案。
事实证实,C往递增方向枚举会超时,而往递减方向枚举就过了。至于为何你们能够根据(1)式进行分析,这里就不阐述了
我用的时间是3.44s,后来发现排名榜上第一名是0.34s,在此膜拜一下orz
1 #include<stdio.h> 2 #include<math.h> 3 #define LL long long 4 int main(){ 5 LL t,a,c,s; 6 scanf("%lld",&t); 7 while(t--){ 8 scanf("%lld",&a); 9 c=a+sqrt(1.0*a*a+1.0); 10 while((1+c*c)%(c-a)!=0)c--; 11 printf("%lld\n",(1+c*c)/(c-a)); 12 } 13 return 0; 14 }