Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

Re:为神马这题有1400+个ac但pascal的却只有16个?答案内详

Posted by stafp at 2011-08-04 21:00:39 on Problem 1981
In Reply To:为神马这题有1400+个ac但pascal的却只有16个?答案内详 Posted by:xuhaoran510 at 2011-06-29 22:36:26
> 1.这道题目数据出的比较尴尬。如果用O(n^3)朴素算法水的话,C++是可以水过去的,但pascal不管怎么
> 常数优化都水不过去。
> 2.那好吧,我用O(n^2lgn)的算法吧。但这时蛋疼的事情出现了:由于需要获得两个圆相交的弧的角度,
> 需要用arctan和arctan2.但这两个东西在math单元里才有,而且math单元被POJ封掉了(很奇
> 怪,C++/G++并没有封掉math.h,但pascal封掉了unit math)。于是pascal悲剧了。
> 3.没事!我自己泰勒展开+各种特判手动写arctan和arctan2!写完了,精度不够。怎么调eps、迭代次数
> 都没用。再次悲剧。
> 4.好吧……我去翻free pascal的source code,把math单元源码翻一遍,总能找到这东西的实现的!翻
> 完,发现没有……(这一点我不能肯定,毕竟没有函数原型却能编译出来一个函数是不现实的事。但我Ctrl+F
> 了numlib文件夹中的每一个文件,都没有找到arctan和arctan2的函数原型,更没有函数实现了,不知原
> 因)。
> 5.最后……把math库里arcsin的实现复制过来当arctan用,手动写arctan2,终于ac了……而且因为中途
> 多了一步sqrt,只要多写一个浮点除法精度就又不够了。
> 
> 帮助pascal党后人,留下pascal版atan2的实现,需要的可以去用
> 前两个函数来自math单元源码,最后一个是我手写的。
> 
> arfloat0   = array[0..20000] of extended;
> 
> function spepol(x: extended; var a: extended; n: longint): extended;
> var   pa : ^arfloat0;
>        i : longint;
>     polx : extended;
> begin
>   pa:=@a;
>   polx:=0;
>   for i:=n downto 0 do
>     polx:=polx*x+pa^[i];
>   spepol:=polx
> end;
> 
> function spears(x: extended): extended;
> const
> 
>     pi2 = 1.570796326794897;
>     a : array[0..17] of extended =
>     (  1.047197551196598e+0, 5.375149359132719e-2, 7.798902238957732e-3,
>        1.519668539582420e-3, 3.408637238430600e-4, 8.302317819598986e-5,
>        2.134554822576075e-5, 5.701781046148566e-6, 1.566985123962741e-6,
>        4.402076871418002e-7, 1.257811162594110e-7, 3.646577948300129e-8,
>        1.081021746966715e-8, 3.212744286269388e-9, 8.515014302985799e-10,
>        2.513296398553196e-10, 1.342121568282535e-10, 4.210346761190271e-11);
> 
> var    y, u, t, s : extended;
>     uprang        : boolean;
> begin
>   u:=sqr(x); uprang:= u > 0.5;
>   if uprang
>   then
>     u:=1-u;
>   t:=4*u-1; y:=spepol(t, a[0], sizeof(a) div sizeof(extended) - 1);
>   if uprang
>   then
>     begin
>       s:=pi2-sqrt(u)*y;
>       if x < 0
>       then
>         s:=-s;
>       spears:=s
>     end
>   else
>     spears:=x*y
> end;
> 
> function atan2(const x,y:extended):extended;
> var res:extended;
> begin if x=0 then if y<0 then exit(pi) else exit(0);
>       if y=0 then if x<0 then exit(-pi/2) else exit(pi/2);
>       res:=spears(y/sqrt(sqr(x)+sqr(y)));
> 	if (y>0)and(x>0) then exit(pi/2-res);
>       if (y>0)and(x<0) then exit(-pi/2+res);
>       if (y<0)and(x>0) then exit(pi/2-res);
>       if (y<0)and(x<0) then exit(-pi/2+res);
> end;
> 
> 

以前用PASCAL写某题(INK BLOCK?)的时候也曾经手写过arctan2,但是那个精度哪有楼主这个NB....Orz啊

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator