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]

      

  • 相关阅读:
    SQL SERVER 2005中同义词实例
    内聚性是模块之所以成为模块的原因--一个中心、单一职责
    软件开发的方法论
    系统集成与软件开发
    编程的本质是构建---建构你想要表达的世界
    编程思想与以人为本-编程的本质
    软件开发之道-软件开发背后的哲学
    swift 协议(结合扩展)的特点
    swift的特性:扩展、协议、泛型
    从数据流角度管窥 Moya 的实现(一):构建请求
  • 原文地址:https://www.cnblogs.com/Tunix/p/4496898.html
Copyright © 2011-2022 走看看