SPOJ 1440.Use of Function Arctan

  第一次遇到這種限制代碼長度的題!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 }
相關文章
相關標籤/搜索