SGU 120 解题手记
表示在复平面上将(x,y)绕原点逆时针旋转θ。那么(x,y)绕原点逆时针旋转θ后得到的点就是
。
θ可以很容易的得出。将给出的一个点绕多边形中心不断旋转θ,即可得到正多边形。
这题的正多边形中心并不是原点,所以还要想办法把中心求出来,才能用上面的公式。


这里,N1代表编号较小的点,根据N1和N2的位置关系,有上面两种情况。但O点的求法可以统一为,将向量P逆时针旋转θ(这个θ跟前面旋转公式里的θ没有关系),然后将长度放大
。化简得到
。
Submit 1: WA on 2。好像精度不够,比如这组数据得到的结果就很糟:
6 1 4 0 10 0 -10
-0.000000 10.000002 8.660255 5.000001 8.660255 -5.000000 0.000000 -10.000001 -8.660254 -5.000000 -8.660254 5.000000
不仅如此,还写出了这样的语句,让相关变量互相更新:O.x=O.x-O.y*tanth; O.y=O.x*tanth+O.y;
精度的问题是因存储各点的坐标时误用float类型产生的。
Submit 2: WA on 6。精度仍然有问题,有些应该输出0.000000的地方输出-0.000000。不过发现一个AC的标程也有这样的问题。求O点的地方写错了。
Submit 3: WA on 2。求O点的地方又写错了。
Submit 4: WA on 6。MaShuo提出,π的定义应该用系统函数或者系统常量,不要写3.14...。他认为自己写3.14...的话,在后面的三角函数运算中会产生很大的误差。
Submit 5: WA on 6。实在不知道为什么错了,开始使用“控制变量法”——用标程中的关键语句代替我的程序中的语句,逐步找出问题所在。这次更换我的程序中旋转给出点的方法——从逆时针旋转改到顺时针旋转。
Submit 6: WA on 1。有个n1+1写成了n2-1,是由于替换不完善造成的。
Submit 7: WA on 2。算O点用到的θ错了。
Submit 8: WA on 6。θ还是错的。
Submit 9: WA on 2。θ还是错的。
Submit 10: AC。不容易啊……交了10次才过……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #include <cstdio> #include <cmath> #include <algorithm> using namespace std; #define PI 3.1415926535897932 struct point { double x,y; }; inline double format(double a) { return fabs(a)<1e-7?0:a; } int main() { point O,point1,point2,points[151]; int n,n1,n2; scanf("%d%d%d",&n,&n1,&n2); scanf("%lf%lf%lf%lf",&point1.x,&point1.y,&point2.x,&point2.y); if (n2<n1) { swap(n1,n2); swap(point1,point2); } point mid={(point1.x+point2.x)/2,(point1.y+point2.y)/2}; double theta=PI*(n2-n1)/n; if (n2-n1<n/2) theta+=PI*3/2; else theta-=PI/2; double tanth=tan(theta); O.x=mid.x-(mid.y-point1.y)*tanth; O.y=(mid.x-point1.x)*tanth+mid.y; points[n1].x=point1.x-=O.x; points[n1].y=point1.y-=O.y; double sina=sin(PI*2/n),cosa=cos(PI*2/n); for (int i=1,j=n1+1;i<n;i++,j++) { if (j>n) j-=n; points[j].x=+point1.x*cosa+point1.y*sina; points[j].y=-point1.x*sina+point1.y*cosa; point1=points[j]; } for (int i=1;i<=n;i++) printf("%.6lf %.6lf\n",format(points[i].x+O.x),format(points[i].y+O.y)); return 0; } |
