zoukankan      html  css  js  c++  java
  • POJ 3525 Most Distant Point from the Sea (半平面交向内推进+二分半径)

    题目链接

    题意 : 给你一个多边形,问你里边能够盛的下的最大的圆的半径是多少。

    思路 :先二分半径r,半平面交向内推进r。模板题

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <iostream>
      4 #include <math.h>
      5 const double eps = 1e-10 ;
      6 
      7 using namespace std ;
      8 
      9 struct node
     10 {
     11     double x;
     12     double y ;
     13 } p[150],temp[150],newp[150];//p是最开始的多边形的每个点,temp是中间过程中临时存的多边形的每个点,newp是切割后的多边形的每个点
     14 int n,newn ;//原来的点数,切割后的点数
     15 double a,b,c ;//直线方程的三个系数
     16 
     17 void getline(node x,node y)//求x与y两点确定的直线方程ax+by+c=0
     18 {
     19     a = y.y-x.y ;
     20     b = x.x-y.x ;
     21     c = y.x*x.y - y.y*x.x ;
     22 }
     23 node intersect(node x,node y)//求x与y点确定的直线与ax+by+c=0这条直线的交点
     24 {
     25     double u = fabs(a*x.x+b*x.y+c) ;
     26     double v = fabs(a*y.x+b*y.y+c) ;
     27     node t ;
     28     t.x = (x.x*v+y.x*u)/(u+v) ;//y.y-x.y=u+v;y.y-t.y=v;y.y-x.y=u;
     29     t.y = (x.y*v+y.y*u)/(u+v) ;
     30     return t ;
     31 }
     32 void cut()
     33 {
     34     int cutn = 0 ;
     35     for(int i = 1 ; i <= newn ; i++)
     36     {
     37         if(a*newp[i].x+b*newp[i].y+c >= 0)//所有的点都大于0,说明所有的点都在这条直线的另一边,所以不用切
     38             temp[ ++cutn] = newp[i] ;
     39         else
     40         {
     41             if(a*newp[i-1].x+b*newp[i-1].y+c > 0)
     42                 temp[++cutn ] = intersect(newp[i-1],newp[i]) ;//把新交点加入
     43             if(a*newp[i+1].x+b*newp[i+1].y+c > 0)
     44                 temp[ ++cutn] = intersect(newp[i+1],newp[i]) ;
     45         }
     46     }
     47     for(int i = 1 ; i <= cutn ; i++)
     48         newp[i] = temp[i] ;
     49     newp[cutn+1] = temp[1] ;//能够找出所有点的前驱和后继
     50     newp[0] = temp[cutn] ;
     51     newn = cutn ;
     52 }
     53 double dist(double x,double y)
     54 {
     55     return sqrt(x*x+y*y) ;
     56 }
     57 bool solve(double r)
     58 {
     59     for(int i = 1 ; i <= n ; i++)
     60     {
     61         newp[i] = p[i] ;
     62     }
     63     p[n+1] = p[1] ;
     64     newp[n+1] = newp[1] ;
     65     newp[0] = newp[n] ;
     66     newn = n ;
     67     for(int i = 1 ; i <= n ; i++)
     68     {
     69         node t1,t2,t ;
     70         t.x = p[i+1].y-p[i].y ;
     71         t.y = p[i].x-p[i+1].x ;
     72         double k = r/dist(t.x,t.y) ;
     73         t.x *= k ;
     74         t.y *= k ;
     75         t1.x = t.x+p[i].x ;
     76         t1.y = t.y+p[i].y ;
     77         t2.x = t.x+p[i+1].x ;
     78         t2.y = t.y+p[i+1].y ;
     79         getline(t1,t2) ;//从头开始顺序遍历两个相邻点。
     80         cut() ;
     81     }
     82     if(newn == 0)
     83         return false ;
     84     else return true ;
     85 //求多边形核的面积
     86 //    double s = 0 ;
     87 //    for(int i = 1 ; i <= newn ; i++)
     88 //        s += newp[i].x*newp[i+1].y-newp[i].y*newp[i+1].x ;
     89 //    return s = fabs(s/2.0) ;
     90 }
     91 void guizhenghua()
     92 {
     93     for(int i = 1 ; i < (n+1)/2 ; i++)//规整化方向,顺时针变逆时针,逆时针变顺时针。
     94         swap(p[i],p[n-i]) ;
     95 }
     96 int main()
     97 {
     98     while(scanf("%d",&n)!=EOF && n)
     99     {
    100         for(int i = 1 ; i <= n ; i++)
    101             scanf("%lf %lf",&p[i].x,&p[i].y) ;
    102         guizhenghua();
    103         p[n+1] = p[1] ;
    104         double high = 99999999 ,low = 0.0,mid ;
    105         while(high-low >= eps)
    106         {
    107             mid = (low+high)/2.0 ;
    108             if(solve(mid)) low = mid ;
    109             else high = mid ;
    110         }
    111         printf("%lf
    ",high) ;
    112     }
    113     return 0;
    114 }
    View Code
  • 相关阅读:
    愤怒
    Eclipse的调试功能的10个小窍门
    PL/SQL之基础篇
    PL/SQL之高级篇
    luogu P1015 回文数
    Noip2011 提高组 Day1 T3 Mayan游戏
    各种各样的——玄学卡常技巧
    北京清北 综合强化班 Day5
    [UVA12003] Array Transformer(分块,二分,暴力)
    [POJ3468] A Simple Problem with Integers(分块)
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3959697.html
Copyright © 2011-2022 走看看