1. 程式人生 > >POJ3384:Feng Shui——題解

POJ3384:Feng Shui——題解

str 個數 printf amp 可能 gpo eps poi sin

http://poj.org/problem?id=3384

題目大意:給一個順時針序的多邊形,求在裏面放半徑為r的兩個圓使得兩圓覆蓋的面積最大,求出這樣的圓的坐標。

————————————————

解題思路:將多邊形內縮進r,然後求內核。

枚舉點對然後根據點對距離判斷是否覆蓋面積最大即可。

註意:可能兩圓重合。

#include<cstdio>
#include<queue>
#include
<cctype> #include<cstring> #include<stack> #include<cmath> #include<algorithm> using namespace std; typedef double dl; const dl eps=1e-10; const int N=301; struct Point{ dl x; dl y; }p[N],point[N],q[N],z; //point,初始點 //q,暫時存可行點 //p,記錄可行點 int n,curcnt,cnt; dl r;
//curcnt,暫時存可行點個數 //cnt,記錄可行點個數 inline Point getmag(Point a,Point b){ Point s; s.x=b.x-a.x;s.y=b.y-a.y; return s; } inline dl multiX(Point a,Point b){ return a.x*b.y-b.x*a.y; } inline void getline(Point x,Point y,dl &a,dl &b,dl &c){ a=y.y-x.y; b=x.x-y.x; c
=y.x*x.y-x.x*y.y; return; } inline Point intersect(Point x,Point y,dl a,dl b,dl c){ Point s; dl u=fabs(a*x.x+b*x.y+c); dl v=fabs(a*y.x+b*y.y+c); s.x=(x.x*v+y.x*u)/(u+v); s.y=(x.y*v+y.y*u)/(u+v); return s; } inline void cut(dl a,dl b,dl c){ curcnt=0; for(int i=1;i<=cnt;i++){ if(a*p[i].x+b*p[i].y+c>-eps)q[++curcnt]=p[i]; else{ if(a*p[i-1].x+b*p[i-1].y+c>eps){ q[++curcnt]=intersect(p[i],p[i-1],a,b,c); } if(a*p[i+1].x+b*p[i+1].y+c>eps){ q[++curcnt]=intersect(p[i],p[i+1],a,b,c); } } } for(int i=1;i<=curcnt;i++)p[i]=q[i]; p[curcnt+1]=p[1];p[0]=p[curcnt]; cnt=curcnt; return; } inline void init(){ for(int i=1;i<=n;i++)p[i]=point[i]; z.x=z.y=0; p[n+1]=p[1]; p[0]=p[n]; point[n+1]=point[1]; cnt=n; return; } inline void regular(){//調換方向 for(int i=1;i<(n+1)/2;i++)swap(point[i],point[n-i]); return; } inline dl dis(Point a,Point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } inline void solve(){ init(); for(int i=1;i<=n;i++){ Point ta,tb,tt; tt.x=point[i+1].y-point[i].y; tt.y=point[i].x-point[i+1].x; dl k=r/sqrt(tt.x*tt.x+tt.y*tt.y); tt.x*=k;tt.y*=k; ta.x=point[i].x+tt.x; ta.y=point[i].y+tt.y; tb.x=point[i+1].x+tt.x; tb.y=point[i+1].y+tt.y; dl a,b,c; getline(ta,tb,a,b,c); cut(a,b,c); } return; } int main(){ scanf("%d%lf",&n,&r); for(int i=1;i<=n;i++){ scanf("%lf%lf",&point[i].x,&point[i].y); } solve(); int x,y; dl res=-1; for(int i=1;i<=cnt;i++){ for(int j=i;j<=cnt;j++){ dl tmp=dis(p[i],p[j]); if(tmp>res){ res=tmp; x=i; y=j; } } } printf("%.4f %.4f %.4f %.4f\n",p[x].x,p[x].y,p[y].x,p[y].y); return 0; }

POJ3384:Feng Shui——題解