zoukankan      html  css  js  c++  java
  • 【POJ】【2068】Art Gallery

    计算几何/半平面交


      裸的半平面交,关于半平面交的入门请看神犇博客:http://blog.csdn.net/accry/article/details/6070621

      然而代码我是抄的proverbs的……

      大体思路是这样的:(一个增量算法)

        维护一个当前的半平面交的点集,每次用一条直线去cut它:

          依次枚举“凸包”上的点,点在直线左边则保留下来了,否则就丢掉=。=

          同时判一下如果“凸包”上连续的两个点分别在直线两侧,就加入这条“凸包”上的线段与直线的交点= =

        然后新点集get!

      最后求个面积>_>

      有个trick是如果给的顺序是顺时针,需要反转成逆时针(用算多边形面积的方法就可以判断,如果是逆时针,面积为正)

      1 Source Code
      2 Problem: 1279        User: sdfzyhy
      3 Memory: 720K        Time: 32MS
      4 Language: G++        Result: Accepted
      5 
      6     Source Code
      7 
      8     //POJ 1279
      9     #include<cmath>
     10     #include<vector>
     11     #include<cstdio>
     12     #include<cstring>
     13     #include<cstdlib>
     14     #include<iostream>
     15     #include<algorithm>
     16     #define rep(i,n) for(int i=0;i<n;++i)
     17     #define F(i,j,n) for(int i=j;i<=n;++i)
     18     #define D(i,j,n) for(int i=j;i>=n;--i)
     19     #define pb push_back
     20     using namespace std;
     21     inline int getint(){
     22         int v=0,sign=1; char ch=getchar();
     23         while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
     24         while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
     25         return v*sign;
     26     }
     27     const int N=1e5+10;
     28     const double INF=1e9;
     29     typedef long long LL;
     30     /******************tamplate*********************/
     31     const double eps=1e-8;
     32     int dcmp(double x){return x>eps ? 1 : x<-eps ? -1 : 0;}
     33     struct Poi{
     34         double x,y;
     35         Poi(){}
     36         Poi(double x,double y):x(x),y(y){}
     37         void read(){scanf("%lf%lf",&x,&y);}
     38     }p[N],tp[N],s[N],o;
     39     typedef Poi Vec;
     40     Vec operator - (const Poi&a,const Poi &b){return Vec(a.x-b.x,a.y-b.y);}
     41 
     42     int n;
     43     double Cross(const Vec &a,const Vec &b){return a.x*b.y-a.y*b.x;}
     44     double getarea(Poi *p,int n){
     45         double ans=0.0;
     46         F(i,1,n) ans+=Cross(p[i]-o,p[i+1]-o);
     47         return ans*0.5;
     48     }
     49     Poi getpoint(const Poi &a,const Poi &b,const Poi &c,const Poi &d){
     50         Poi ans,tmp=b-a;
     51         double k1=Cross(d-a,c-a),k2=Cross(c-b,d-b);
     52         ans.x=a.x+tmp.x*k1/(k1+k2);
     53         ans.y=a.y+tmp.y*k1/(k1+k2);
     54         return ans;
     55     }
     56 
     57     void init(){
     58         n=getint();
     59         F(i,1,n) p[i].read();
     60         p[n+1]=p[1];
     61     }
     62     void Change(){
     63         F(i,1,n>>1) swap(p[i],p[n-i+1]);
     64         p[n+1]=p[1];
     65     }
     66     void getcut(){
     67         tp[1]=tp[5]=Poi(-INF,-INF);
     68         tp[2]=Poi(INF,-INF);
     69         tp[3]=Poi(INF,INF);
     70         tp[4]=Poi(-INF,INF);
     71         int num=4,size=0;
     72         F(i,1,n){
     73             size=0;
     74             F(j,1,num){
     75                 if (dcmp(Cross(p[i+1]-p[i],tp[j]-p[i]))>=0)
     76                     s[++size]=tp[j];
     77                 if (dcmp(Cross(p[i+1]-p[i],tp[j]-p[i]) * 
     78                          Cross(p[i+1]-p[i],tp[j+1]-p[i]))<0) 
     79                     s[++size]=getpoint(p[i],p[i+1],tp[j],tp[j+1]);
     80             }
     81             s[size+1]=s[1];
     82             F(j,1,size+1) tp[j]=s[j];
     83             num=size;
     84         }
     85         n=num;
     86     }
     87     int main(){
     88     #ifndef ONLINE_JUDGE
     89         freopen("1279.in","r",stdin);
     90         freopen("1279.out","w",stdout);
     91     #endif
     92         int T=getint();
     93         while(T--){
     94             init();
     95             if (dcmp(getarea(p,n))<=0) Change();
     96             getcut();
     97             printf("%.2f
    ",fabs(getarea(s,n)));
     98         }
     99         return 0;
    100     }
    View Code
    Art Gallery
    Time Limit: 1000MS   Memory Limit: 10000K
    Total Submissions: 5805   Accepted: 2455

    Description

    The art galleries of the new and very futuristic building of the Center for Balkan Cooperation have the form of polygons (not necessarily convex). When a big exhibition is organized, watching over all of the pictures is a big security concern. Your task is that for a given gallery to write a program which finds the surface of the area of the floor, from which each point on the walls of the gallery is visible. On the figure 1. a map of a gallery is given in some co-ordinate system. The area wanted is shaded on the figure 2.

    Input

    The number of tasks T that your program have to solve will be on the first row of the input file. Input data for each task start with an integer N, 5 <= N <= 1500. Each of the next N rows of the input will contain the co-ordinates of a vertex of the polygon ? two integers that fit in 16-bit integer type, separated by a single space. Following the row with the co-ordinates of the last vertex for the task comes the line with the number of vertices for the next test and so on.

    Output

    For each test you must write on one line the required surface - a number with exactly two digits after the decimal point (the number should be rounded to the second digit after the decimal point).

    Sample Input

    1
    7
    0 0
    4 4
    4 7
    9 7
    13 -1
    8 -6
    4 -4

    Sample Output

    80.00

    Source

    [Submit]   [Go Back]   [Status]   [Discuss]

      

  • 相关阅读:
    LAMP 服务器环境
    LAMP 环境搭建
    为何程序员总喜欢写技术博客,看完恍然大悟...
    沉入海底2年的微软数据中心浮出水面:故障率只有陆地上的1/8,除了长点贝类和藻类完全没问题...
    真正毁掉一个人的,是“打工者心态”
    包装严重的 IT 行业,作为面试官,我是如何甄别应聘者的包装程度
    一名测试实习生的心路历程(二)
    7年赚的2个亿,数学家6年就花光了,全砸在自家的房子上
    “蚂蚁牙黑,蚂蚁呀吼”一夜间火遍全网?别忽略了潜在风险
    面试常问的 25+ 个 Linux 命令
  • 原文地址:https://www.cnblogs.com/Tunix/p/4496898.html
Copyright © 2011-2022 走看看