zoukankan      html  css  js  c++  java
  • poj 3384 Feng Shui 半平面交

    给定一个多边形,在多边形内放有两个相同的圆,使两个圆尽可能多的覆盖多边形。输出最终两个圆心的位置。
    最优的放置方法必定是圆内切于两条边,那么把所有的边向内推移半径R的距离,得到新的多边形(也有可能是一个点或一条直线),求出新多边形相距最远的两个顶点,这两个顶点就是圆心的位置了。
     
      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<iostream>
      4 #include<cmath>
      5 using namespace std;
      6 const double pi=acos(-1.0);
      7 const int N=105;
      8 const double eps=1e-9;
      9 int n,m,s;
     10 struct point
     11 {
     12     double x,y;
     13 }p[N],q[N],input[N];
     14 int sig(double k)
     15 {
     16     return (k<-eps)?-1:(k>eps);
     17 }
     18 double dis(point a,point b)
     19 {
     20     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     21 }
     22 double xmule(point p1,point p2,point p3)
     23 {
     24     return ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y));
     25 }
     26 void interect(point x,point y,double a,double b,double c)//求2直线交点(xy与ax0+by0+c=0的交点)
     27 {
     28     double u=fabs(a*x.x+b*x.y+c);
     29     double v=fabs(a*y.x+b*y.y+c);
     30     q[++s].x=(x.x*v+y.x*u)/(u+v);
     31     q[s].y=(x.y*v+y.y*u)/(u+v);
     32 }
     33 void cut(double a,double b,double c)//半平面切割
     34 {
     35     s=0;
     36     int i;
     37     for(i=1;i<=m;i++)//枚举所有点
     38     {
     39         if(sig(a*p[i].x+b*p[i].y+c)<=0)
     40         {
     41             q[++s]=p[i];//符合
     42         }
     43         else
     44         {
     45             if(sig(a*p[i-1].x+b*p[i-1].y+c)<0)
     46                 interect(p[i-1],p[i],a,b,c);//p[i]p[i-1]与直线的交点符合
     47             if(sig(a*p[i+1].x+b*p[i+1].y+c)<0)
     48                 interect(p[i],p[i+1],a,b,c);//p[i]p[i+1]与直线的交点符合
     49         }
     50     }
     51     for(i=1;i<=s;i++)
     52     {
     53         p[i]=q[i];//更新
     54     }
     55     p[0]=p[s];
     56     p[s+1]=p[1];
     57     m=s;
     58 }
     59 double dir(point a,point b)
     60 {
     61     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     62 }
     63 int main()
     64 {
     65     int i,j,ans1,ans2,r;
     66     double mid,max,len;
     67     while(scanf("%d%d",&n,&r)!=EOF)
     68     {
     69         for(i=1;i<=n;i++)
     70         {
     71             scanf("%lf%lf",&input[i].x,&input[i].y);
     72             p[i]=input[i];
     73         }
     74         input[n+1]=input[1];
     75         p[0]=p[n];
     76         p[n+1]=p[1];
     77         double a,b,c;
     78         point tt,ta,tb;
     79         for(i=1;i<=n;i++)
     80         {
     81             p[i]=input[i];
     82         }
     83         p[0]=p[n];
     84         p[n+1]=p[1];
     85         m=n;
     86         for(i=1;i<=n;i++)
     87         {
     88             tt.x=input[i+1].y-input[i].y;//顺时针,注意顺序,每条边一起向“内”推进R
     89             tt.y=input[i].x-input[i+1].x;
     90             double k=r*1.0/sqrt(tt.x*tt.x+tt.y*tt.y);
     91             tt.x=tt.x*k;
     92             tt.y=tt.y*k;
     93             ta.x=input[i].x+tt.x;
     94             ta.y=input[i].y+tt.y;
     95             tb.x=input[i+1].x+tt.x;
     96             tb.y=input[i+1].y+tt.y;
     97             
     98             a=ta.y-tb.y;//由2点求出直线ax+by+c=0
     99             b=tb.x-ta.x;
    100             c=ta.x*tb.y-ta.y*tb.x;
    101             cut(a,b,c);
    102         }
    103         max=-1;
    104         ans1=m;
    105         ans2=m;
    106         for(i=1;i<m;i++)
    107             for(j=i+1;j<=m;j++)
    108             {
    109                 len=dir(p[i],p[j]);
    110                 if(len-max>eps)
    111                 {
    112                     max=len;
    113                     ans1=i;
    114                     ans2=j;
    115                 }
    116             }
    117             printf("%.4f %.4f %.4f %.4f\n",p[ans1].x,p[ans1].y,p[ans2].x,p[ans2].y);
    118     }
    119     return 0;
    120 }
     



  • 相关阅读:
    nginx error_log报错upstream timed out (110: Connection timed out)
    ubuntu12.04 nginx添加ssl认证
    TP5.0:同一个控制器访问不同方法
    TP5.0:的安装与配置
    html常用的小技能
    详情介绍win7:编辑文件夹时提示操作无法完成,因为其中的文件夹或文件已在另一个程序中打开的解决过程
    详细讲解:通过phpstudy 设置站点域名、站点域名管理
    tp3.2.3自定义全局函数的使用
    详细讲解:tp3.2.3生成验证码并进行验证(ajax校验返回及自定义返回)
    WPS去掉英语单词下面的红斜线
  • 原文地址:https://www.cnblogs.com/zxj015/p/2740210.html
Copyright © 2011-2022 走看看