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]

      

  • 相关阅读:
    Node开发--->10_Node.js_mongoDB增删改查操作
    Node开发--->9_Node.js_数据库概述及环境搭建
    Node开发--->8_Node.js异步编程
    Node开发--->7_服务器端开发
    Node开发--->6_服务器端开发
    Node开发--->5_nodejs中的模块加载机制
    Node开发--->4_package.json文件
    Node开发--->3_node模块化开发之第三方模块
    Node开发--->2_node模块化开发之系统模块
    2015-7-22 积累的力量
  • 原文地址:https://www.cnblogs.com/Tunix/p/4496898.html
Copyright © 2011-2022 走看看