题目给出 n 个矩形,要求它们的面积并。具体做法是离散化。先把 2n 个 x 坐标排序去重,然后再把所有水平线段(要记录是矩形上边还是下边)按 y 坐标排序。最后对于每一小段区间 (x[i], x[i + 1]) 扫描所有的水平线段,求出这些水平线段在小区间内覆盖的面积。总的时间复杂度是 O(n^2)。利用线段树,可以优化到 O(nlogn)。

 

/*************************************************************************
Author: WHU_GCC
Created Time: 2007-8-21 15:56:29
File Name: pku1151.cpp
Description: 
***********************************************************************
*/

#include 
<iostream>
#include 
<cmath>
using namespace std;

#define out(x) (cout << #x << ": " << x << endl)
typedef 
long long int64;
const int maxint = 0x7FFFFFFF;
const int64 maxint64 = 0x7FFFFFFFFFFFFFFFLL;
template 
<class T> void show(T a, int n) for (int i = 0; i < n; ++i) cout << a[i] << ' '; cout << endl; }
template 
<class T> void show(T a, int r, int l) for (int i = 0; i < r; ++i) show(a[i], l); cout << endl; }

const int maxn = 1000;

typedef 
struct line_t
{
    
double l, r, y;
    
int flag;
}
;

bool operator <(const line_t &a, const line_t &b)
{
    
return a.y < b.y;
}


bool d_equal(const double &a, const double &b)
{
    
return abs(a - b) < 1e-9;
}


int n;
double x[maxn];
int cnt_x, cnt_line;
line_t line[maxn];

int main()
{
    
int ca = 1;
    
while (scanf("%d"&n), n != 0)
    
{
        cnt_x 
= 0;
        cnt_line 
= 0;
        
for (int i = 0; i < n; i++)
        
{
            
double x1, y1, x2, y2;
            scanf(
"%lf%lf%lf%lf"&x1, &y1, &x2, &y2);
            x[cnt_x
++= x1;
            x[cnt_x
++= x2;
            line[cnt_line].flag 
= 0;
            line[cnt_line].l 
= x1;
            line[cnt_line].r 
= x2;
            line[cnt_line
++].y = y1;
            line[cnt_line].flag 
= 1;
            line[cnt_line].l 
= x1;
            line[cnt_line].r 
= x2;
            line[cnt_line
++].y = y2;
        }

        sort(line, line 
+ cnt_line);
        sort(x, x 
+ cnt_x);
        cnt_x 
= unique(x, x + cnt_x, d_equal) - x;

        
double area = 0.0;
        
for (int i = 0; i < cnt_x - 1; i++)
        
{
            
int cnt = 0;
            
double now_y;
            
for (int j = 0; j < cnt_line; j++if (line[j].l <= x[i] && line[j].r >= x[i + 1])
            
{
                
if (cnt == 0) now_y = line[j].y;
                
if (line[j].flag == 0) cnt++;
                
else cnt--;
                
if (cnt == 0) area += (x[i + 1- x[i]) * (line[j].y - now_y);
            }

        }

        printf(
"Test case #%d\n", ca++);
        printf(
"Total explored area: %.2lf\n\n", area);
    }

    
return 0;
}
posted on 2007-08-21 16:39 Felicia 阅读(544) 评论(1)  编辑 收藏 引用 所属分类: 计算几何
Comments

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理