zoukankan      html  css  js  c++  java
  • poj 3525

    多边形内最大半径圆。

    哇没有枉费了我自闭了这么些天,大概五天前我看到这种题可能毫无思路抓耳挠腮举手投降什么的,现在已经能1A了哇。

    还是先玩一会计算几何,刷个几

    嗯这个半平面交+二分就阔以解决。虽然队友说他施展三分套三分*****

    想象一下,如果一个多边形能放进去半径为r的圆,那么在每条边向里平移r之后,他的内核一定不为空。

    所以我们可以二分r,然后求半平面交,平移操作其实很好处理。

    1A了很开森,去快乐的玩耍惹。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <cmath>
      6 #include <deque>
      7 using namespace std;
      8 typedef double db;
      9 const db eps=1e-6;
     10 const db pi=acos(-1);
     11 int sign(db k){
     12     if (k>eps) return 1; else if (k<-eps) return -1; return 0;
     13 }
     14 int cmp(db k1,db k2){return sign(k1-k2);}
     15 struct point{
     16     db x,y;
     17     point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
     18     point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
     19     point operator * (db k1) const{return (point){x*k1,y*k1};}
     20     point operator / (db k1) const{return (point){x/k1,y/k1};}
     21     db abs(){return sqrt(x*x+y*y);}
     22     point unit(){db w=abs(); return point{x/w,y/w};}
     23     point turn90(){ return point{-y,x};}
     24     db getP()const { return sign(y)==1||(sign(y)==0&&sign(x)==-1);}
     25 };
     26 db cross(point k1,point k2){ return k1.x*k2.y-k1.y*k2.x;}
     27 db dot(point k1,point k2){ return k1.x*k2.x+k1.y*k2.y;}
     28 db rad(point k1,point k2){ return atan2(cross(k1,k2),dot(k1,k2));}
     29 int compareangle(point k1,point k2){
     30     return k1.getP()<k2.getP()||(k1.getP()==k2.getP()&&sign(cross(k1,k2))>0);
     31 }
     32 point getLL(point k1,point k2,point k3,point k4){
     33     db w1=cross(k1-k3,k4-k3),w2=cross(k4-k3,k2-k3);
     34     return (k1*w2+k2*w1)/(w1+w2);
     35 }
     36 struct line{
     37     point p[2];
     38     line(point k1,point k2){p[0]=k1;p[1]=k2;}
     39     point &operator[](int k){ return p[k];}
     40     int include(point k){ return sign(cross(p[1]-p[0],k-p[0])>0);}
     41     point dir(){ return p[1]-p[0];}
     42     line push(db eps){//向左手边平移eps
     43         //const db eps=1e-6;
     44         point delta=(p[1]-p[0]).turn90().unit()*eps;
     45         return {p[0]-delta,p[1]-delta};
     46     }
     47 };
     48 point getLL(line k1,line k2){
     49     return getLL(k1[0],k1[1],k2[0],k2[1]);
     50 }
     51 int parallel(line k1,line k2){ return sign(cross(k1.dir(),k2.dir()))==0;}
     52 int sameDir(line k1,line k2){
     53     return parallel(k1,k2)&&sign(dot(k1.dir(),k2.dir()))==1;
     54 }
     55 int operator <(line k1,line k2){
     56     if(sameDir(k1,k2))return k2.include(k1[0]);
     57     return compareangle(k1.dir(),k2.dir());
     58 }
     59 int checkpos(line k1,line k2,line k3){ return k3.include(getLL(k1,k2));}
     60 vector<line> getHL(vector<line> &L){
     61     sort(L.begin(),L.end());deque<line> q;
     62     for(int i=0;i<L.size();i++){
     63         if(i&&sameDir(L[i],L[i-1]))continue;
     64         while (q.size()>1&&!checkpos(q[q.size()-2],q[q.size()-1],L[i]))q.pop_back();
     65         while (q.size()>1&&!checkpos(q[1],q[0],L[i]))q.pop_front();
     66         q.push_back(L[i]);
     67     }
     68     while (q.size()>2&&!checkpos(q[q.size()-2],q[q.size()-1],q[0]))q.pop_back();
     69     while (q.size()>2&&!checkpos(q[1],q[0],q[q.size()-1]))q.pop_front();
     70     vector<line> ans;for(int i=0;i<q.size();i++)ans.push_back(q[i]);
     71     return ans;
     72 }
     73 point p[1551];
     74 int n;
     75 bool cw(){//时针
     76     db s=0;
     77     for(int i=1;i<n-1;i++){
     78         s+=cross(p[i]-p[0],p[i+1]-p[0]);
     79     }
     80     return s>0;
     81 }
     82 vector<line> L,tmp;
     83 bool check(db x){
     84     tmp.clear();
     85     for(int i=0;i<L.size();i++){
     86         tmp.push_back(L[i].push(-x));
     87     }
     88     tmp = getHL(tmp);
     89     if(tmp.size()>=3)
     90         return true;
     91     return false;
     92 }
     93 int main(){
     94     //freopen("3525.in","r",stdin);
     95     while (scanf("%d",&n)&&n){
     96         for(int i=0;i<n;i++){
     97             scanf("%lf%lf",&p[i].x,&p[i].y);
     98         }
     99         if(!cw())reverse(p,p+n);
    100         for(int i=0;i<n;i++){
    101             L.push_back(line(p[i],p[(i+1)%n]));
    102         }
    103         db l = 0,r=100000.0;
    104         while (l+0.0000001<r){
    105             db mid = (l+r)/2;
    106             if(check(mid))
    107                 l=mid;
    108             else
    109                 r=mid;
    110         }
    111         printf("%.7f
    ",l);
    112         L.clear();
    113     }
    114 }
    View Code
  • 相关阅读:
    MySQL密码复杂度与密码过期策略介绍
    mysql 5.7安装密码校验插件validate_password
    MySQL安装控制插件(Connection-Control)--可有效的防止客户端暴力登录的风险(攻击)
    Liunx 无法杀掉reids进程解决方法
    Linux安装Kafka
    ZooKeeper安装及简单操作
    关于数组的算法题(一)
    集合框架方法(用于算法)
    Spring简答题(一)
    java选择题(三)
  • 原文地址:https://www.cnblogs.com/MXang/p/10454111.html
Copyright © 2011-2022 走看看