第一次遇到這種限制代碼長度的題!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 }