程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ1279 Art Gallery

POJ1279 Art Gallery

編輯:C++入門知識

 

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 4300   Accepted: 1849

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 -4Sample Output

80.00
思考:求多邊形的核,給出的多邊形點的順序可能是逆序也可能是順序,給出的最大數的范圍16-bit integer type。用C++提交AC,用G++提交WA。有時間學習一下兩則的不同。

半平面問題的第一題,很興奮!
[cpp]
#include <iostream> 
 #include <cstdio>  
#include <algorithm>  
#include <cmath> 
 #include <vector> 
 #include <complex>
   using namespace std;
 const int maxn = 2000; 
const double inf = 1e5; 
const double eps = 1e-10;
 //1279  Accepted    348K 
  0MS C++ 3482B   2013-06-04 09:13:50 
 struct point {      double x; 
    double y;   
  point(){}      point( double a, double b):x(a), y(b){}   
  friend point operator - (const point &a, const point &b) { 
        return point(a.x-b.x, a.y-b.y);  
   }  }; 
  double det(const point &a, const point &b) {  
   return a.x*b.y - a.y*b.x;  } 
  struct polygon {      int n;   

  point a[maxn];  };  //把直線化為一般式。
  struct halfPlane {      double a, b, c; 
    halfPlane(point p, point q) {          a = q.y - p.y;  
       b = p.x - q.x;          c = det(q, p);      }  }; 
  struct polygon_convex {      vector <point> P;  }; 
  double calc(halfPlane &L, point &a) {   
  return a.x*L.a + a.y*L.b + L.c;  }
   point Intersect(point &a, point &b, halfPlane &L) {   
  point res;  
   double t1 = calc(L, a), t2 = calc(L,  b);
     res.x = (t2*a.x - t1*b.x)/(t2-t1); 
    res.y = (t2*a.y - t1*b.y)/(t2-t1); 
    return res;  }  //將一個凸多邊形和一個半平面交。
   polygon_convex cut(polygon_convex &a, halfPlane &L) {  
   int n = a.P.size();      polygon_convex res;   
  for(int i = 0; i < n; i++) {       
  if(calc(L, a.P[i])<-eps) {         
    res.P.push_back(a.P[i]);          } 
        else {              int j;   
          j = i - 1;       
      if(j < 0) j = n-1;  
           if(calc(L, a.P[j])<-eps) 
                res.P.push_back(Intersect(a.P[j], a.P[i],L));
              j = i + 1;         
    if(j==n) j = 0;   
          if(calc(L, a.P[j])<-eps)   
              res.P.push_back(Intersect(a.P[i], a.P[j], L));      
   }      }      return res;  }  //參數為一個多邊形, 返回一個凸多邊形。
  polygon_convex core(polygon &a) {      polygon_convex res;  
   res.P.clear(); 
 //清空容器.       res.P.push_back(point(-inf, -inf));  
   res.P.push_back(point(inf, -inf));  
   res.P.push_back(point(inf, inf));
     res.P.push_back(point(-inf, inf));   
  int n = a.n; 
    if(n==2) {          halfPlane L(a.a[0], a.a[1]);    
     return res = cut(res, L);  
   }    
 for(int i = 0; i < n ; i++) {     
    halfPlane L(a.a[i], a.a[(i+1)%n]);//多邊形循環產生n個半平面。  
        // printf("%.2lf, %.2lf, %.2lf\n", L.a, L.b, L.c); 
         res = cut(res, L);//用產生的半平面調用cut去一次次切割。
      }      return res;//還回凸多邊形.   } 
  //如果多邊形是順時針給出,則改變方向.
  polygon init(polygon v) {      int n = v.n;  
   double area = 0;   
  for(int i = 1; i < n-1; i++) {       
  area += det(v.a[i]-v.a[0], v.a[i+1]-v.a[0]);  
   }      if(area < 0) {          polygon temp;  
       temp.n = n;          temp.a[0] = v.a[0];    
     for(int i = n-1; i >= 1; i--) {          
   temp.a[n-i] = v.a[i];          }        
 return temp;      }      return v;  }  
 double get_area(polygon_convex v) {    
 double area = 0;      int n = v.P.size(); 
    for(int i = 1; i < n-1; i++) {       
  area += det(v.P[i]-v.P[0], v.P[i+1]-v.P[0]); 
    }      return area/2;  }    int main()  {  
   polygon v;      point tmp;  
   int T;    
 int n;      scanf("%d", &T);   
  while(T--) {          scanf("%d", &n);   
      v.n = 0;          for(int i = 0; i < n; i++) {   
          scanf("%lf%lf", &tmp.x, &tmp.y);        
     v.a[i] = tmp;              v.n++;  //別忘了。    
      }          v = init(v);     
    polygon_convex ans = core(v);      
   double result = get_area(ans);     
    printf("%.2lf\n", result);      }      return 0;  } 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved