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 }
相关文章
相关标签/搜索