Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
为神马这题有1400+个ac但pascal的却只有16个?答案内详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; Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator