HDU 4033 Regular Polygon【二分】
题意: 知道了正多边形内部一个点和其他所有点的距离,假如此正多边形存在则输出此正多边形边长,否则输出 impossible。
分析:二分多边形的边长,对于每一个边长求出对应的内角和,假如内角和小与 360,则此边长比实际值要小,否则大于实际边长。
#include<stdio.h> #include<string.h> #include<math.h> const double eps=1e-6; const double P=acos(-1.0); double d[105]; double ab(double a) { return a>0?a:-a; } int n; double angle(double x) { double ang; double ans=0; int i; for(i=0;i<n;i++) { if(x>d[i]+d[(i+1)%n]-eps) return -1; if(x<ab(d[i]-d[(i+1)%n])) return -2; ang=(d[i]*d[i]+d[(i+1)%n]*d[(i+1)%n]-x*x)/(2.0*d[i]*d[(i+1)%n]); ang=acos(ang); ans+=ang; } return ans; } int main() { int t,i,ca=1; double l,r,mid,tmp,res; scanf("%d",&t); while(t--) { scanf("%d",&n); l=0; r=20000; for(i=0;i<n;i++) scanf("%lf",&d[i]); res=-1; int tim=0; int flag=0; while(l<r+eps) { if(ab(r-l)<eps) { tim++; if(tim>=2) break; } mid=(l+r)/2; tmp=angle(mid); if(ab(tmp-2*P)<eps) { flag=1; break; } if(tmp==-1||tmp>2*P+eps) r=mid; else l=mid; } printf("Case %d: ",ca++); if(flag) printf("%.3lf\n",mid); else printf("impossible\n"); } return 0; }