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 |
Re:为神马这题有1400+个ac但pascal的却只有16个?答案内详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: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator