hdu 4629

题意:给你n个三角形,问覆盖1~n次的面积各是多少,n < 50;

分析:取出所有端点和交点的x坐标,排序,然后对于每一段xi~xi+1的范围的线段都是不相交的,所以组成的

面积要么是三角形,要么是梯形,可以直接用公式算面积,然后对于每一个三角形的线段都标记该段对于

从下往上的扫描线来说是入边还是出边,然后就可以直接计算出这块面积被覆盖了几次;如入边加1,出边减一

下图,黄色表示覆盖次数;

2013多校第三场

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<vector>
  7 #include<cstdlib>
  8 #define pbk push_back
  9 using namespace std;
 10 const int N = 25050+10;
 11 const double eps = 1e-10;
 12 inline double sqr(double x){
 13     return x * x;
 14 }
 15 inline int dcmp(double x){
 16     return x < -eps ? -1 : x > eps;
 17 }
 18 struct Point{
 19     double x,y;
 20     int kind;
 21     Point(){}
 22     Point(double x,double y,int kind = 0):x(x),y(y),kind(kind){}
 23     bool operator < (const Point &p)const{
 24         return dcmp(x - p.x) < 0 || ( dcmp(x - p.x) == 0 && dcmp(y - p.y) < 0 );
 25     }
 26     Point operator - (const Point &p)const{
 27         return Point(x - p.x, y - p.y);
 28     }
 29     Point operator + (const Point &p)const{
 30         return Point(x + p.x, y + p.y);
 31     }
 32     Point operator * (const double &k)const{
 33         return Point (x*k , y*k);
 34     }
 35     Point operator / (const double &k)const{
 36         return Point (x/k, y/k);
 37     }
 38     double operator * (const Point &p)const{
 39         return x * p.y - y * p.x;
 40     }
 41     double operator / (const Point &p)const{
 42         return x * p.x + y * p.y;
 43     }
 44     void input(){
 45         scanf("%lf%lf",&x,&y);
 46     }
 47     void ot(){
 48         printf("%lf %lf\n",x,y);
 49     }
 50 };
 51 struct Line{
 52     Point a,b;
 53     int kind;
 54     Line (){}
 55     Line (Point a,Point b,int kind = 0):a(a),b(b),kind(kind){}
 56     double operator * (const Point &p)const{
 57         return ( b - a ) * ( p - a );
 58     }
 59     double operator / (const Point &p)const{
 60         return ( p - a) / ( p - b);
 61     }
 62     bool parallel(const Line &v){
 63         return !dcmp( ( b - a ) * ( v.b - v.a ) ); 
 64     }
 65     int LineCrossLine(const Line &v){
 66         if ( (*this).parallel(v) ){
 67             return ( dcmp( v * a ) == 0);
 68         }return 2;
 69     }
 70     int SegCrossSeg(const Line &v){
 71         int d1 = dcmp( (*this) * v.a);
 72         int d2 = dcmp( (*this) * v.b);
 73         int d3 = dcmp( v * a);
 74         int d4 = dcmp( v * b);
 75         if ( ( d1 ^ d2 ) == -2 && ( d3 ^ d4 ) == -2 ) return 2;
 76         return ( ( d1 == 0 && dcmp( (*this) / v.a ) <= 0 )
 77             ||   ( d2 == 0 && dcmp( (*this) / v.b ) <= 0 )
 78             ||   ( d3 == 0 && dcmp( v / a ) <= 0 )
 79             ||   ( d4 == 0 && dcmp( v / b ) <= 0 )
 80             );
 81     }
 82     Point CrossPoint(const Line &v){
 83         double s1 = v * a, s2 = v * b;
 84         return ( a * s2 - b * s1) / (s2 - s1);
 85     }
 86     void input(){
 87         a.input(); b.input();
 88     }
 89     void ot(){
 90         a.ot(); b.ot();
 91     }
 92 
 93 };
 94 
 95 int n,poly_n,xn;
 96 vector<double> lx;
 97 vector<Line> line;
 98 double ans[N];
 99 void init(){
100     int sz = line.size();
101     for (int i = 0; i < sz; i++){
102         for (int j = i+1; j < sz; j++){
103             if (line[i].SegCrossSeg(line[j]) == 2){
104                 Point p = line[i].CrossPoint(line[j]);
105                 lx.pbk(p.x);
106             }
107         }
108     }
109     
110     sort(lx.begin(),lx.end());
111     xn = unique(lx.begin(),lx.end()) - lx.begin();
112 }
113 vector<Point> qu[N];
114 void work(){
115     for (int i = 0; i <= n; i++) ans[i] = 0;
116     for (int i = 0; i < xn-1; i++){
117         int k = 0;
118         for (int j = 0; j+1 < qu[i].size(); j++){
119             k += qu[i][j].kind;
120             ans[ k ] += (lx[i+1] - lx[i]) * (qu[i][j+1].x+qu[i][j+1].y - qu[i][j].x - qu[i][j].y) / 2;        
121         }
122     }
123     for (int i = 1; i <= n; i++) printf("%.10lf\n",ans[i]);
124 }
125 void check(){
126     for (int i = 0; i < xn - 1; i++){
127         cout<<qu[i].size()<<" >.<"<<endl;
128         for (int j = 0; j < qu[i].size(); j++){
129             qu[i][j].ot(); cout<<qu[i][j].kind<<endl;
130         }
131     }
132 }
133 void solve(){
134     for (int i = 0; i < xn; i++) qu[i].clear();
135     for (int i = 0; i < line.size(); i++){
136         int j = lower_bound(lx.begin(),lx.begin()+xn,line[i].a.x) - lx.begin();
137         for (; j+1 < xn; j++ ){
138             double l = lx[j], r = lx[j+1];
139             if (dcmp(r - line[i].b.x) > 0) break;
140             Point p1 = line[i].CrossPoint(Line(Point(l,0), Point(l,1)));
141             Point p2 = line[i].CrossPoint(Line(Point(r,0), Point(r,1)));
142             qu[j].pbk(Point(p1.y, p2.y,line[i].kind));
143         }
144     }
145     for (int i = 0; i < xn - 1; i++) sort(qu[i].begin(), qu[i].end());
146 //    check();
147     work();
148 }
149 int main(){
150     int T; scanf("%d",&T);
151     while (T--){
152         scanf("%d",&n);
153         lx.clear(); line.clear();;
154         for (int i = 0; i < n ;i++){
155             Point t[4];
156             for (int j = 0; j < 3; j++ ){
157                 t[j].input(); 
158             }
159             t[3] = t[0];
160             int flag = 1;
161             if (dcmp( (t[1] - t[0])*(t[2] - t[0]) ) == 0) flag = 0;
162         
163             for (int i = 0; i < 3 && flag; i++ ){
164                 lx.pbk(t[i].x);
165                 for (int j = i+1; j < 3; j++){
166                     Line tmp; tmp.a = t[i]; tmp.b = t[j];
167                     if (dcmp( tmp.a.x - tmp.b.x ) > 0) swap(tmp.a, tmp.b);
168                     
169                     Line tmp2 = Line(t[3-i-j], Point(t[3-i-j].x, t[3-i-j].y - 1));
170                     if (tmp.LineCrossLine(tmp2) != 2) continue;
171                     Point tp = tmp.CrossPoint(tmp2);
172                     if (dcmp(tp.y - t[3-i-j].y) < 0) tmp.kind = 1;
173                         else tmp.kind = -1;    
174                     line.pbk(tmp);
175                 }
176             }
177         }
178         init();
179         solve();    
180     }
181     return 0;
182 }
View Code

相关文章: